From 251013c223af7299f2cd902947bb6f0aa4eca092 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 14 Jan 2025 15:40:12 +0100 Subject: [PATCH 01/20] add prebuilt rule upgrade preview integration tests --- .../rule_assets/prebuilt_rule_asset.mock.ts | 2 +- .../trial_license_complete_tier/index.ts | 21 + .../review_prebuilt_rule_upgrade.ts | 7057 +++++++++++++++++ .../create_prebuilt_rule_saved_objects.ts | 5 +- .../prebuilt_rules/set_up_rule_upgrade.ts | 60 + 5 files changed, 7142 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts index 6442582c1b573..2b5d1d4701d7a 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts @@ -109,7 +109,7 @@ export const getPrebuiltNewTermsRuleSpecificFieldsMock = (): NewTermsRuleCreateF query: 'user.name: *', language: 'kuery', new_terms_fields: ['user.name'], - history_window_start: '1h', + history_window_start: 'now-1h', }); export const getPrebuiltEsqlRuleSpecificFieldsMock = (): EsqlRuleCreateFields => ({ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 72707393c0527..dae72176f4c4e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -27,5 +27,26 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); + // loadTestFile(require.resolve('./bootstrap_prebuilt_rules')); + // loadTestFile(require.resolve('./get_prebuilt_rules_status')); + // loadTestFile(require.resolve('./get_prebuilt_timelines_status')); + // loadTestFile(require.resolve('./install_prebuilt_rules')); + // loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); + // loadTestFile(require.resolve('./upgrade_prebuilt_rules')); + // loadTestFile(require.resolve('./upgrade_prebuilt_rules_with_historical_versions')); + // loadTestFile(require.resolve('./fleet_integration')); + // loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.all_rules_mode')); + // loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.specific_rules_mode')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.single_line_string_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.scalar_array_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.multi_line_string_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.data_source_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.kql_query_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); + // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); + loadTestFile(require.resolve('./review_prebuilt_rule_upgrade')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts new file mode 100644 index 0000000000000..7b3953e2a7cd8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts @@ -0,0 +1,7057 @@ +/* + * 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 expect from 'expect'; +import { + DataSourceType, + KqlQueryType, + RuleFieldsDiff, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + reviewPrebuiltRulesToUpgrade, +} from '../../../../utils'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; +import { setUpRuleUpgrade } from '../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +interface FieldTestData { + name: string; + assets: Parameters[0]['assets']; + expectedFieldsDiff: Partial; + expectedStats: Record; + expectedFieldsDiffStats: Record; +} + +const FIELDS_TEST_DATA: Record = { + // Common fields + name: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + expectedFieldsDiff: { + name: { + base_version: 'Original name', + current_version: 'Original name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Original name', + }, + }, + expectedFieldsDiff: { + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Original name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + expectedFieldsDiff: { + name: { + base_version: 'Original name', + current_version: 'Updated name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + expectedFieldsDiff: { + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Updated name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + description: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + expectedFieldsDiff: { + description: { + base_version: 'Original description', + current_version: 'Original description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Original description', + }, + }, + expectedFieldsDiff: { + description: { + base_version: 'Original description', + current_version: 'Customized description', + target_version: 'Original description', + merged_version: 'Customized description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + expectedFieldsDiff: { + description: { + base_version: 'Original description', + current_version: 'Updated description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }, + expectedFieldsDiff: { + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 3', + merged_version: + 'Customized description\nOriginal description line 1\nOriginal description line 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + expectedFieldsDiff: { + description: { + base_version: 'Original description', + current_version: 'Customized description', + target_version: 'Updated description', + merged_version: 'Customized description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + tags: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + expectedFieldsDiff: { + tags: { + base_version: ['tagA'], + current_version: ['tagA'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagC'], + }, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }, + expectedFieldsDiff: { + tags: { + base_version: ['tagA'], + current_version: ['tagC'], + target_version: ['tagA'], + merged_version: ['tagC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + expectedFieldsDiff: { + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }, + expectedFieldsDiff: { + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagC'], + merged_version: ['tagB', 'tagC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + ], + severity: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: {}, + upgrade: { + type: 'query', + severity: 'medium', + }, + }, + expectedFieldsDiff: { + severity: { + base_version: 'low', + current_version: 'low', + target_version: 'medium', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'high', + }, + upgrade: { + type: 'query', + severity: 'low', + }, + }, + expectedFieldsDiff: { + severity: { + base_version: 'low', + current_version: 'high', + target_version: 'low', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'high', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + expectedFieldsDiff: { + severity: { + base_version: 'low', + current_version: 'high', + target_version: 'high', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + expectedFieldsDiff: { + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'high', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + severity_mapping: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '20', + }, + ], + }, + }, + expectedFieldsDiff: { + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '20', + }, + ], + merged_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '20', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'low', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + }, + expectedFieldsDiff: { + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'low', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'low', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + }, + expectedFieldsDiff: { + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + expectedFieldsDiff: { + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + risk_score: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 50, + }, + }, + expectedFieldsDiff: { + risk_score: { + base_version: 10, + current_version: 10, + target_version: 50, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 30, + }, + upgrade: { + type: 'query', + risk_score: 10, + }, + }, + expectedFieldsDiff: { + risk_score: { + base_version: 10, + current_version: 30, + target_version: 10, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 40, + }, + upgrade: { + type: 'query', + risk_score: 40, + }, + }, + expectedFieldsDiff: { + risk_score: { + base_version: 10, + current_version: 40, + target_version: 40, + merged_version: 40, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + expectedFieldsDiff: { + risk_score: { + base_version: 10, + current_version: 50, + target_version: 30, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + risk_score_mapping: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '20', + risk_score: 20, + }, + ], + }, + }, + expectedFieldsDiff: { + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '20', + risk_score: 20, + }, + ], + merged_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '20', + risk_score: 20, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + }, + expectedFieldsDiff: { + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + expectedFieldsDiff: { + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + expectedFieldsDiff: { + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + references: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + expectedFieldsDiff: { + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-1', 'http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }, + expectedFieldsDiff: { + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1', 'http://url-2'], + target_version: ['http://url-1'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-1', 'http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + expectedFieldsDiff: { + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1', 'http://url-2'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-3'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + expectedFieldsDiff: { + references: { + base_version: ['http://url-1'], + current_version: ['http://url-3'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-3', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + ], + false_positives: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example1', 'example2'], + }, + }, + expectedFieldsDiff: { + false_positives: { + base_version: ['example1'], + current_version: ['example1'], + target_version: ['example1', 'example2'], + merged_version: ['example1', 'example2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example1', 'example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }, + expectedFieldsDiff: { + false_positives: { + base_version: ['example1'], + current_version: ['example1', 'example2'], + target_version: ['example1'], + merged_version: ['example1', 'example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example1', 'example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example1', 'example2'], + }, + }, + expectedFieldsDiff: { + false_positives: { + base_version: ['example1'], + current_version: ['example1', 'example2'], + target_version: ['example1', 'example2'], + merged_version: ['example1', 'example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example3'], + }, + upgrade: { + type: 'query', + false_positives: ['example1', 'example2'], + }, + }, + expectedFieldsDiff: { + false_positives: { + base_version: ['example1'], + current_version: ['example3'], + target_version: ['example1', 'example2'], + merged_version: ['example3'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + threat: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + expectedFieldsDiff: { + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + }, + expectedFieldsDiff: { + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + expectedFieldsDiff: { + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + }, + }, + expectedFieldsDiff: { + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + note: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'new note', + }, + }, + expectedFieldsDiff: { + note: { + base_version: 'some note', + current_version: 'some note', + target_version: 'new note', + merged_version: 'new note', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'some note', + }, + }, + expectedFieldsDiff: { + note: { + base_version: 'some note', + current_version: 'updated note', + target_version: 'some note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + expectedFieldsDiff: { + note: { + base_version: 'some note', + current_version: 'updated note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + note: 'line 1\nline 2', + }, + patch: { + note: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + note: 'line 1\nline 3', + }, + }, + expectedFieldsDiff: { + note: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + expectedFieldsDiff: { + note: { + base_version: 'some note', + current_version: 'customized note', + target_version: 'updated note', + merged_version: 'customized note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + setup: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'new setup', + }, + }, + expectedFieldsDiff: { + setup: { + base_version: 'some setup', + current_version: 'some setup', + target_version: 'new setup', + merged_version: 'new setup', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }, + expectedFieldsDiff: { + setup: { + base_version: 'some setup', + current_version: 'updated setup', + target_version: 'some setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + expectedFieldsDiff: { + setup: { + base_version: 'some setup', + current_version: 'updated setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + setup: 'line 1\nline 2', + }, + patch: { + setup: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + setup: 'line 1\nline 3', + }, + }, + expectedFieldsDiff: { + setup: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + expectedFieldsDiff: { + setup: { + base_version: 'some setup', + current_version: 'customized setup', + target_version: 'updated setup', + merged_version: 'customized setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + related_integrations: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + ], + }, + }, + expectedFieldsDiff: { + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + }, + expectedFieldsDiff: { + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + }, + expectedFieldsDiff: { + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + expectedFieldsDiff: { + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + required_fields: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + expectedFieldsDiff: { + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + }, + expectedFieldsDiff: { + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + expectedFieldsDiff: { + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', + }, + ], + }, + }, + expectedFieldsDiff: { + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + rule_schedule: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + expectedFieldsDiff: { + rule_schedule: { + base_version: { + interval: '5m', + lookback: '300s', + }, + current_version: { + interval: '5m', + lookback: '300s', + }, + target_version: { + interval: '5m', + lookback: '600s', + }, + merged_version: { + interval: '5m', + lookback: '600s', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + }, + expectedFieldsDiff: { + rule_schedule: { + base_version: { + interval: '5m', + lookback: '300s', + }, + current_version: { + interval: '5m', + lookback: '900s', + }, + target_version: { + interval: '5m', + lookback: '300s', + }, + merged_version: { + interval: '5m', + lookback: '900s', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', + to: 'now', + }, + }, + expectedFieldsDiff: { + rule_schedule: { + base_version: { + interval: '5m', + lookback: '300s', + }, + current_version: { + interval: '5m', + lookback: '900s', + }, + target_version: { + interval: '5m', + lookback: '900s', + }, + merged_version: { + interval: '5m', + lookback: '900s', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + expectedFieldsDiff: { + rule_schedule: { + base_version: { + interval: '5m', + lookback: '300s', + }, + current_version: { + interval: '5m', + lookback: '900s', + }, + target_version: { + interval: '5m', + lookback: '600s', + }, + merged_version: { + interval: '5m', + lookback: '900s', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + max_signals: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + expectedFieldsDiff: { + max_signals: { + base_version: 100, + current_version: 100, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 100, + }, + }, + expectedFieldsDiff: { + max_signals: { + base_version: 100, + current_version: 130, + target_version: 100, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 150, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + expectedFieldsDiff: { + max_signals: { + base_version: 100, + current_version: 150, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + expectedFieldsDiff: { + max_signals: { + base_version: 100, + current_version: 130, + target_version: 150, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + rule_name_override: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + expectedFieldsDiff: { + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldA' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }, + expectedFieldsDiff: { + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldA' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + expectedFieldsDiff: { + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }, + expectedFieldsDiff: { + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldC' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + timestamp_override: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + expectedFieldsDiff: { + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldA', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }, + expectedFieldsDiff: { + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldA', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + expectedFieldsDiff: { + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }, + expectedFieldsDiff: { + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldC', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + timeline_template: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + expectedFieldsDiff: { + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }, + expectedFieldsDiff: { + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + expectedFieldsDiff: { + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }, + expectedFieldsDiff: { + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + building_block: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + expectedFieldsDiff: { + // @ts-expect-error testing versions equals undefined + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: '', + }, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }, + expectedFieldsDiff: { + // @ts-expect-error testing versions equals undefined + building_block: { + base_version: { type: 'default' }, + target_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + }, + expectedFieldsDiff: { + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + target_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + expectedFieldsDiff: { + // @ts-expect-error testing versions equals undefined + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + investigation_fields: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + expectedFieldsDiff: { + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldA'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }, + expectedFieldsDiff: { + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldA'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + expectedFieldsDiff: { + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }, + expectedFieldsDiff: { + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldC'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + 'data_source (index patterns)': [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + merged_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexB', 'indexC'], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + ], + 'data_source (data view)': [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }, + expectedFieldsDiff: { + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + alert_suppression: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + expectedFieldsDiff: { + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldA'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }, + expectedFieldsDiff: { + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldA'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + expectedFieldsDiff: { + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }, + expectedFieldsDiff: { + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldC'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // Custom Query, Saved Query, Threat Match, Threshold, New Terms + kql_query: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'query', + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: 'query', + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + expectedFieldsDiff: { + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'query', + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + query: '*:*', + }, + upgrade: { + type: 'query', + query: 'process.name:*.exe', + language: 'kuery', + }, + }, + expectedFieldsDiff: { + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'query', + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + query: '*:*', + }, + upgrade: { + type: 'query', + query: '*:*', + language: 'kuery', + }, + }, + expectedFieldsDiff: { + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'query', + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + query: '*:*', + }, + upgrade: { + type: 'query', + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + expectedFieldsDiff: { + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // EQL + eql_query: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + expectedFieldsDiff: { + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + }, + expectedFieldsDiff: { + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + expectedFieldsDiff: { + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + expectedFieldsDiff: { + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // ES|QL + esql_query: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + expectedFieldsDiff: { + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + }, + expectedFieldsDiff: { + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + expectedFieldsDiff: { + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + }, + expectedFieldsDiff: { + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // Threat Match + threat_index: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + expectedFieldsDiff: { + threat_index: { + base_version: ['indexA'], + current_version: ['indexA'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }, + expectedFieldsDiff: { + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexA'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + expectedFieldsDiff: { + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }, + expectedFieldsDiff: { + threat_index: { + base_version: ['indexA'], + current_version: ['indexD'], + target_version: ['indexB', 'indexC'], + merged_version: ['indexD', 'indexB', 'indexC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + ], + threat_query: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + expectedFieldsDiff: { + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }, + expectedFieldsDiff: { + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + expectedFieldsDiff: { + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }, + expectedFieldsDiff: { + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + threat_mapping: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + expectedFieldsDiff: { + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + }, + expectedFieldsDiff: { + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + expectedFieldsDiff: { + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + }, + }, + expectedFieldsDiff: { + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + threat_indicator_path: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + expectedFieldsDiff: { + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldA', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }, + expectedFieldsDiff: { + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldA', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + expectedFieldsDiff: { + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }, + expectedFieldsDiff: { + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldC', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // Threshold + threshold: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + expectedFieldsDiff: { + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldA'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }, + expectedFieldsDiff: { + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldA'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + expectedFieldsDiff: { + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }, + expectedFieldsDiff: { + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldC'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // Machine Learning + machine_learning_job_id: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + expectedFieldsDiff: { + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobA'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }, + expectedFieldsDiff: { + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobA'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + expectedFieldsDiff: { + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }, + expectedFieldsDiff: { + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobC'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + anomaly_threshold: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + expectedFieldsDiff: { + anomaly_threshold: { + base_version: 10, + current_version: 10, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }, + expectedFieldsDiff: { + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 10, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + expectedFieldsDiff: { + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }, + expectedFieldsDiff: { + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 30, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }, + }, + ], + // New Terms + new_terms_fields: [ + { + name: 'returns non-customized field with an upgrade (AAB diff case)', + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + expectedFieldsDiff: { + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldA'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field without an upgrade (ABA diff case)', + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }, + expectedFieldsDiff: { + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with a matching upgrade (ABB diff case)', + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + expectedFieldsDiff: { + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }, + expectedFieldsDiff: { + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA', 'fieldC'], + merged_version: ['fieldB', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + { + name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldC'], + }, + }, + expectedFieldsDiff: { + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldC'], + merged_version: ['fieldB', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }, + expectedStats: { + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }, + expectedFieldsDiffStats: { + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }, + }, + ], +}; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + const deps = { es, supertest, log }; + + for (const [fieldName, fieldTestDataArray] of Object.entries(FIELDS_TEST_DATA)) { + describe(`review upgrade preview for "${fieldName}" field`, () => { + for (const fieldTestData of fieldTestDataArray) { + it(fieldTestData.name, async () => { + await setUpRuleUpgrade({ + assets: fieldTestData.assets, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject(fieldTestData.expectedStats); + expect(reviewResponse.rules[0].diff).toMatchObject( + fieldTestData.expectedFieldsDiffStats + ); + expect(reviewResponse.rules[0].diff.fields).toMatchObject( + fieldTestData.expectedFieldsDiff + ); + }); + } + }); + } + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts index 3ebd928123cc4..9a8897891d812 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts @@ -42,9 +42,10 @@ export const createRuleAssetSavedObject = (overrideParams: Partial( - type: T['type'] + type: T['type'], + rewrites?: Partial ) => ({ - 'security-rule': getPrebuiltRuleMockOfType(type), + 'security-rule': { ...getPrebuiltRuleMockOfType(type), ...rewrites }, ...ruleAssetSavedObjectESFields, }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts new file mode 100644 index 0000000000000..099ea907ef147 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -0,0 +1,60 @@ +/* + * 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 type { ToolingLog } from '@kbn/tooling-log'; +import { RuleResponse } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { PrebuiltRuleAsset } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules'; +import type { Client } from '@elastic/elasticsearch'; +import type SuperTest from 'supertest'; +import { + createHistoricalPrebuiltRuleAssetSavedObjects, + createRuleAssetSavedObjectOfType, +} from './create_prebuilt_rule_saved_objects'; +import { patchRule } from '../patch_rule'; +import { installPrebuiltRules } from './install_prebuilt_rules'; + +interface SetUpRuleUpgradeDeps { + supertest: SuperTest.Agent; + log: ToolingLog; + es: Client; +} + +type PartialPrebuiltRuleAsset = Pick & Partial; + +interface RuleUpgradeAssets { + installed: PartialPrebuiltRuleAsset; + patch: Partial; + upgrade: PartialPrebuiltRuleAsset; +} + +interface SetUpRuleUpgradeParams { + assets: RuleUpgradeAssets; + deps: SetUpRuleUpgradeDeps; +} + +export async function setUpRuleUpgrade({ assets, deps }: SetUpRuleUpgradeParams): Promise { + await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ + createRuleAssetSavedObjectOfType(assets.installed.type, { + rule_id: 'rule-1', + version: 1, + ...assets.installed, + }), + ]); + await installPrebuiltRules(deps.es, deps.supertest); + await patchRule(deps.supertest, deps.log, { + rule_id: 'rule-1', + ...assets.patch, + }); + + await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ + createRuleAssetSavedObjectOfType(assets.upgrade.type, { + rule_id: 'rule-1', + version: 2, + ...assets.upgrade, + }), + ]); +} From e073668e56e940917f922a99644ceaa9cdc53539 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 21 Jan 2025 10:01:49 +0100 Subject: [PATCH 02/20] refactor upgrade review tests --- .../trial_license_complete_tier/index.ts | 2 + .../review_prebuilt_rule_upgrade.ts | 7057 ----------------- .../alert_suppression.ts | 331 + .../anomaly_threshold.ts | 336 + .../building_block.ts | 324 + .../data_source.ts | 647 ++ .../description.ts | 383 + .../review_prebuilt_rule_upgrade/eql_query.ts | 421 + .../esql_query.ts | 412 + .../false_positives.ts | 331 + .../history_window_start.ts | 336 + .../review_prebuilt_rule_upgrade/index.ts | 112 + .../investigation_fields.ts | 331 + .../kql_query.inline_query.ts | 450 ++ .../kql_query.saved_query.ts | 374 + .../machine_learning_job_id.ts | 336 + .../max_signals.ts | 331 + .../review_prebuilt_rule_upgrade/name.ts | 331 + .../new_terms_fields.ts | 336 + .../review_prebuilt_rule_upgrade/note.ts | 377 + .../references.ts | 331 + .../related_integrations.ts | 553 ++ .../required_fields.ts | 545 ++ .../risk_score.ts | 331 + .../risk_score_mapping.ts | 597 ++ .../rule_name_override.ts | 331 + .../rule_schedule.ts | 435 + .../review_prebuilt_rule_upgrade/setup.ts | 377 + .../review_prebuilt_rule_upgrade/severity.ts | 333 + .../severity_mapping.ts | 597 ++ .../review_prebuilt_rule_upgrade/tags.ts | 331 + .../review_prebuilt_rule_upgrade/threat.ts | 673 ++ .../threat_index.ts | 336 + .../threat_indicator_path.ts | 336 + .../threat_mapping.ts | 348 + .../threat_query.ts | 432 + .../review_prebuilt_rule_upgrade/threshold.ts | 336 + .../timeline_template.ts | 350 + .../timestamp_override.ts | 331 + .../prebuilt_rules/set_up_rule_upgrade.ts | 12 +- 40 files changed, 14415 insertions(+), 7058 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index dae72176f4c4e..3087e45c1a97b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -17,6 +17,8 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./upgrade_prebuilt_rules')); loadTestFile(require.resolve('./upgrade_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); + loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.all_rules_mode')); + loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.specific_rules_mode')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.single_line_string_fields')); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts deleted file mode 100644 index 7b3953e2a7cd8..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade.ts +++ /dev/null @@ -1,7057 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - DataSourceType, - KqlQueryType, - RuleFieldsDiff, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - reviewPrebuiltRulesToUpgrade, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; -import { setUpRuleUpgrade } from '../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -interface FieldTestData { - name: string; - assets: Parameters[0]['assets']; - expectedFieldsDiff: Partial; - expectedStats: Record; - expectedFieldsDiffStats: Record; -} - -const FIELDS_TEST_DATA: Record = { - // Common fields - name: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: {}, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - expectedFieldsDiff: { - name: { - base_version: 'Original name', - current_version: 'Original name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Original name', - }, - }, - expectedFieldsDiff: { - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Original name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Updated name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - expectedFieldsDiff: { - name: { - base_version: 'Original name', - current_version: 'Updated name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - expectedFieldsDiff: { - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Updated name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - description: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: {}, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - expectedFieldsDiff: { - description: { - base_version: 'Original description', - current_version: 'Original description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Customized description', - }, - upgrade: { - type: 'query', - description: 'Original description', - }, - }, - expectedFieldsDiff: { - description: { - base_version: 'Original description', - current_version: 'Customized description', - target_version: 'Original description', - merged_version: 'Customized description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Updated description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - expectedFieldsDiff: { - description: { - base_version: 'Original description', - current_version: 'Updated description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: { - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 3', - }, - }, - expectedFieldsDiff: { - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 3', - merged_version: - 'Customized description\nOriginal description line 1\nOriginal description line 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Customized description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - expectedFieldsDiff: { - description: { - base_version: 'Original description', - current_version: 'Customized description', - target_version: 'Updated description', - merged_version: 'Customized description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - tags: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - expectedFieldsDiff: { - tags: { - base_version: ['tagA'], - current_version: ['tagA'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagC'], - }, - upgrade: { - type: 'query', - tags: ['tagA'], - }, - }, - expectedFieldsDiff: { - tags: { - base_version: ['tagA'], - current_version: ['tagC'], - target_version: ['tagA'], - merged_version: ['tagC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - expectedFieldsDiff: { - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - }, - }, - expectedFieldsDiff: { - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagC'], - merged_version: ['tagB', 'tagC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - ], - severity: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: {}, - upgrade: { - type: 'query', - severity: 'medium', - }, - }, - expectedFieldsDiff: { - severity: { - base_version: 'low', - current_version: 'low', - target_version: 'medium', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'high', - }, - upgrade: { - type: 'query', - severity: 'low', - }, - }, - expectedFieldsDiff: { - severity: { - base_version: 'low', - current_version: 'high', - target_version: 'low', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'high', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - expectedFieldsDiff: { - severity: { - base_version: 'low', - current_version: 'high', - target_version: 'high', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - expectedFieldsDiff: { - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'high', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - severity_mapping: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '20', - }, - ], - }, - }, - expectedFieldsDiff: { - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '20', - }, - ], - merged_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '20', - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'low', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - }, - expectedFieldsDiff: { - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'low', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'low', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - }, - expectedFieldsDiff: { - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - expectedFieldsDiff: { - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - risk_score: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: {}, - upgrade: { - type: 'query', - risk_score: 50, - }, - }, - expectedFieldsDiff: { - risk_score: { - base_version: 10, - current_version: 10, - target_version: 50, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 30, - }, - upgrade: { - type: 'query', - risk_score: 10, - }, - }, - expectedFieldsDiff: { - risk_score: { - base_version: 10, - current_version: 30, - target_version: 10, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 40, - }, - upgrade: { - type: 'query', - risk_score: 40, - }, - }, - expectedFieldsDiff: { - risk_score: { - base_version: 10, - current_version: 40, - target_version: 40, - merged_version: 40, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - expectedFieldsDiff: { - risk_score: { - base_version: 10, - current_version: 50, - target_version: 30, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - risk_score_mapping: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '20', - risk_score: 20, - }, - ], - }, - }, - expectedFieldsDiff: { - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '20', - risk_score: 20, - }, - ], - merged_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '20', - risk_score: 20, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - }, - expectedFieldsDiff: { - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - expectedFieldsDiff: { - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - expectedFieldsDiff: { - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - references: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: {}, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - expectedFieldsDiff: { - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-1', 'http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1'], - }, - }, - expectedFieldsDiff: { - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1', 'http://url-2'], - target_version: ['http://url-1'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-1', 'http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - expectedFieldsDiff: { - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1', 'http://url-2'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-3'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - expectedFieldsDiff: { - references: { - base_version: ['http://url-1'], - current_version: ['http://url-3'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-3', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - ], - false_positives: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: {}, - upgrade: { - type: 'query', - false_positives: ['example1', 'example2'], - }, - }, - expectedFieldsDiff: { - false_positives: { - base_version: ['example1'], - current_version: ['example1'], - target_version: ['example1', 'example2'], - merged_version: ['example1', 'example2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example1', 'example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example1'], - }, - }, - expectedFieldsDiff: { - false_positives: { - base_version: ['example1'], - current_version: ['example1', 'example2'], - target_version: ['example1'], - merged_version: ['example1', 'example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example1', 'example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example1', 'example2'], - }, - }, - expectedFieldsDiff: { - false_positives: { - base_version: ['example1'], - current_version: ['example1', 'example2'], - target_version: ['example1', 'example2'], - merged_version: ['example1', 'example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example3'], - }, - upgrade: { - type: 'query', - false_positives: ['example1', 'example2'], - }, - }, - expectedFieldsDiff: { - false_positives: { - base_version: ['example1'], - current_version: ['example3'], - target_version: ['example1', 'example2'], - merged_version: ['example3'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - threat: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - expectedFieldsDiff: { - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - }, - expectedFieldsDiff: { - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - expectedFieldsDiff: { - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - }, - }, - expectedFieldsDiff: { - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - note: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: {}, - upgrade: { - type: 'query', - note: 'new note', - }, - }, - expectedFieldsDiff: { - note: { - base_version: 'some note', - current_version: 'some note', - target_version: 'new note', - merged_version: 'new note', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'some note', - }, - }, - expectedFieldsDiff: { - note: { - base_version: 'some note', - current_version: 'updated note', - target_version: 'some note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - expectedFieldsDiff: { - note: { - base_version: 'some note', - current_version: 'updated note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - note: 'line 1\nline 2', - }, - patch: { - note: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - note: 'line 1\nline 3', - }, - }, - expectedFieldsDiff: { - note: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - expectedFieldsDiff: { - note: { - base_version: 'some note', - current_version: 'customized note', - target_version: 'updated note', - merged_version: 'customized note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - setup: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: {}, - upgrade: { - type: 'query', - setup: 'new setup', - }, - }, - expectedFieldsDiff: { - setup: { - base_version: 'some setup', - current_version: 'some setup', - target_version: 'new setup', - merged_version: 'new setup', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'some setup', - }, - }, - expectedFieldsDiff: { - setup: { - base_version: 'some setup', - current_version: 'updated setup', - target_version: 'some setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - expectedFieldsDiff: { - setup: { - base_version: 'some setup', - current_version: 'updated setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - setup: 'line 1\nline 2', - }, - patch: { - setup: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - setup: 'line 1\nline 3', - }, - }, - expectedFieldsDiff: { - setup: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - expectedFieldsDiff: { - setup: { - base_version: 'some setup', - current_version: 'customized setup', - target_version: 'updated setup', - merged_version: 'customized setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - related_integrations: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - ], - }, - }, - expectedFieldsDiff: { - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - ], - merged_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - }, - expectedFieldsDiff: { - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - merged_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - }, - expectedFieldsDiff: { - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - merged_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - }, - }, - expectedFieldsDiff: { - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - merged_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - required_fields: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - expectedFieldsDiff: { - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - }, - expectedFieldsDiff: { - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - expectedFieldsDiff: { - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldC', - type: 'string', - }, - ], - }, - }, - expectedFieldsDiff: { - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldC', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - rule_schedule: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: {}, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - expectedFieldsDiff: { - rule_schedule: { - base_version: { - interval: '5m', - lookback: '300s', - }, - current_version: { - interval: '5m', - lookback: '300s', - }, - target_version: { - interval: '5m', - lookback: '600s', - }, - merged_version: { - interval: '5m', - lookback: '600s', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - }, - expectedFieldsDiff: { - rule_schedule: { - base_version: { - interval: '5m', - lookback: '300s', - }, - current_version: { - interval: '5m', - lookback: '900s', - }, - target_version: { - interval: '5m', - lookback: '300s', - }, - merged_version: { - interval: '5m', - lookback: '900s', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-20m', - to: 'now', - }, - }, - expectedFieldsDiff: { - rule_schedule: { - base_version: { - interval: '5m', - lookback: '300s', - }, - current_version: { - interval: '5m', - lookback: '900s', - }, - target_version: { - interval: '5m', - lookback: '900s', - }, - merged_version: { - interval: '5m', - lookback: '900s', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - expectedFieldsDiff: { - rule_schedule: { - base_version: { - interval: '5m', - lookback: '300s', - }, - current_version: { - interval: '5m', - lookback: '900s', - }, - target_version: { - interval: '5m', - lookback: '600s', - }, - merged_version: { - interval: '5m', - lookback: '900s', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - max_signals: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: {}, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - expectedFieldsDiff: { - max_signals: { - base_version: 100, - current_version: 100, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 100, - }, - }, - expectedFieldsDiff: { - max_signals: { - base_version: 100, - current_version: 130, - target_version: 100, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 150, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - expectedFieldsDiff: { - max_signals: { - base_version: 100, - current_version: 150, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - expectedFieldsDiff: { - max_signals: { - base_version: 100, - current_version: 130, - target_version: 150, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - rule_name_override: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - expectedFieldsDiff: { - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldA' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldA', - }, - }, - expectedFieldsDiff: { - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldA' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - expectedFieldsDiff: { - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldC', - }, - }, - expectedFieldsDiff: { - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldC' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - timestamp_override: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - expectedFieldsDiff: { - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldA', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldA', - }, - }, - expectedFieldsDiff: { - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldA', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - expectedFieldsDiff: { - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldC', - }, - }, - expectedFieldsDiff: { - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldC', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - timeline_template: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: {}, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - expectedFieldsDiff: { - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - }, - expectedFieldsDiff: { - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - expectedFieldsDiff: { - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'C', - timeline_title: 'timelineC', - }, - }, - expectedFieldsDiff: { - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - building_block: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: {}, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - expectedFieldsDiff: { - // @ts-expect-error testing versions equals undefined - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: '', - }, - upgrade: { - type: 'query', - building_block_type: 'default', - }, - }, - expectedFieldsDiff: { - // @ts-expect-error testing versions equals undefined - building_block: { - base_version: { type: 'default' }, - target_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: 'custom', - }, - }, - expectedFieldsDiff: { - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - target_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - expectedFieldsDiff: { - // @ts-expect-error testing versions equals undefined - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - investigation_fields: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - expectedFieldsDiff: { - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldA'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - }, - expectedFieldsDiff: { - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldA'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - expectedFieldsDiff: { - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldC'] }, - }, - }, - expectedFieldsDiff: { - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldC'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - 'data_source (index patterns)': [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA'], - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA', 'indexC'], - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexA', 'indexC'], - }, - merged_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexB', 'indexC'], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - ], - 'data_source (data view)': [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: {}, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewA', - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewC', - }, - }, - expectedFieldsDiff: { - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - alert_suppression: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - expectedFieldsDiff: { - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldA'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - }, - expectedFieldsDiff: { - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldA'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - expectedFieldsDiff: { - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldC'] }, - }, - }, - expectedFieldsDiff: { - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldC'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // Custom Query, Saved Query, Threat Match, Threshold, New Terms - kql_query: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'query', - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: 'query', - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - expectedFieldsDiff: { - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'query', - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - query: '*:*', - }, - upgrade: { - type: 'query', - query: 'process.name:*.exe', - language: 'kuery', - }, - }, - expectedFieldsDiff: { - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'query', - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - query: '*:*', - }, - upgrade: { - type: 'query', - query: '*:*', - language: 'kuery', - }, - }, - expectedFieldsDiff: { - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'query', - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - query: '*:*', - }, - upgrade: { - type: 'query', - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - expectedFieldsDiff: { - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // EQL - eql_query: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: {}, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - expectedFieldsDiff: { - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - }, - expectedFieldsDiff: { - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - expectedFieldsDiff: { - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - expectedFieldsDiff: { - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'host where host.name == "something"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'host where host.name == "something"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // ES|QL - esql_query: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: {}, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - expectedFieldsDiff: { - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - }, - expectedFieldsDiff: { - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - expectedFieldsDiff: { - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - }, - expectedFieldsDiff: { - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // Threat Match - threat_index: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - expectedFieldsDiff: { - threat_index: { - base_version: ['indexA'], - current_version: ['indexA'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexA'], - }, - }, - expectedFieldsDiff: { - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexA'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - expectedFieldsDiff: { - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB', 'indexC'], - }, - }, - expectedFieldsDiff: { - threat_index: { - base_version: ['indexA'], - current_version: ['indexD'], - target_version: ['indexB', 'indexC'], - merged_version: ['indexD', 'indexB', 'indexC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - ], - threat_query: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - expectedFieldsDiff: { - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - }, - expectedFieldsDiff: { - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - expectedFieldsDiff: { - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.com', - }, - }, - expectedFieldsDiff: { - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.com', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - threat_mapping: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - }, - expectedFieldsDiff: { - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - }, - expectedFieldsDiff: { - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - }, - expectedFieldsDiff: { - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - }, - }, - expectedFieldsDiff: { - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - threat_indicator_path: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - expectedFieldsDiff: { - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldA', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - }, - expectedFieldsDiff: { - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldA', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - expectedFieldsDiff: { - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldC', - }, - }, - expectedFieldsDiff: { - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldC', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // Threshold - threshold: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: {}, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - expectedFieldsDiff: { - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldA'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - }, - expectedFieldsDiff: { - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldA'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - expectedFieldsDiff: { - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldC' }, - }, - }, - expectedFieldsDiff: { - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldC'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // Machine Learning - machine_learning_job_id: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: {}, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - expectedFieldsDiff: { - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobA'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - }, - expectedFieldsDiff: { - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobA'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - expectedFieldsDiff: { - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobC', - }, - }, - expectedFieldsDiff: { - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobC'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - anomaly_threshold: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: {}, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - expectedFieldsDiff: { - anomaly_threshold: { - base_version: 10, - current_version: 10, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - }, - expectedFieldsDiff: { - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 10, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - expectedFieldsDiff: { - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 30, - }, - }, - expectedFieldsDiff: { - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 30, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }, - }, - ], - // New Terms - new_terms_fields: [ - { - name: 'returns non-customized field with an upgrade (AAB diff case)', - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: {}, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - expectedFieldsDiff: { - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldA'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field without an upgrade (ABA diff case)', - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - }, - expectedFieldsDiff: { - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with a matching upgrade (ABB diff case)', - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - expectedFieldsDiff: { - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA', 'fieldC'], - }, - }, - expectedFieldsDiff: { - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA', 'fieldC'], - merged_version: ['fieldB', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - { - name: 'returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldC'], - }, - }, - expectedFieldsDiff: { - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldC'], - merged_version: ['fieldB', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }, - expectedStats: { - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }, - expectedFieldsDiffStats: { - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }, - }, - ], -}; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - const deps = { es, supertest, log }; - - for (const [fieldName, fieldTestDataArray] of Object.entries(FIELDS_TEST_DATA)) { - describe(`review upgrade preview for "${fieldName}" field`, () => { - for (const fieldTestData of fieldTestDataArray) { - it(fieldTestData.name, async () => { - await setUpRuleUpgrade({ - assets: fieldTestData.assets, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject(fieldTestData.expectedStats); - expect(reviewResponse.rules[0].diff).toMatchObject( - fieldTestData.expectedFieldsDiffStats - ); - expect(reviewResponse.rules[0].diff.fields).toMatchObject( - fieldTestData.expectedFieldsDiff - ); - }); - } - }); - } - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts new file mode 100644 index 0000000000000..90e67b02d456c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function alertSuppressionField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "alert_suppression" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + alert_suppression: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldA'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldA'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldC'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + alert_suppression: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldC'] }, + merged_version: { group_by: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts new file mode 100644 index 0000000000000..ed684a5c2da2f --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function anomalyThresholdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "anomaly_threshold" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + anomaly_threshold: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 10, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 10, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 30, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + anomaly_threshold: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + current_version: 20, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts new file mode 100644 index 0000000000000..e6ba3c06f4fba --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts @@ -0,0 +1,324 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function buildingBlockField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "building_block" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + building_block: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: '', + }, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + target_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + target_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + building_block: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + building_block: { + current_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts new file mode 100644 index 0000000000000..807795215b8eb --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts @@ -0,0 +1,647 @@ +/* + * 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 expect from 'expect'; +import { + DataSourceType, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function dataSourceField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "data_source" field with index patterns', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + merged_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexB', 'indexC'], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + merged_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); + + describe('preview rule upgrade for "data_source" field with data view', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + data_source: { + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts new file mode 100644 index 0000000000000..00f940f133010 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts @@ -0,0 +1,383 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function descriptionField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "description" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + description: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: 'Original description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 3', + merged_version: 'Original description line 1\nOriginal description line 3', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 2', + merged_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description', + current_version: 'Updated description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 3', + merged_version: + 'Customized description\nOriginal description line 1\nOriginal description line 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description', + current_version: 'Customized description', + target_version: 'Updated description', + merged_version: 'Customized description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + description: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + description: { + current_version: 'Customized description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts new file mode 100644 index 0000000000000..e23ad4f49419c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts @@ -0,0 +1,421 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function eqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "eql_query" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + eql_query: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'host where host.name == "something"', + language: 'eql', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + eql_query: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + eql_query: { + current_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts new file mode 100644 index 0000000000000..6b056a9d02432 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts @@ -0,0 +1,412 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function esqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "esql_query" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + esql_query: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + esql_query: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + esql_query: { + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts new file mode 100644 index 0000000000000..db82e03b12e61 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function falsePositivesField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "false_positives" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + false_positives: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example1'], + target_version: ['example2'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example3'], + }, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example3'], + target_version: ['example1'], + merged_version: ['example3'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example2'], + target_version: ['example2'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example2'], + target_version: ['example3'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + false_positives: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + false_positives: { + current_version: ['example2'], + target_version: ['example3'], + merged_version: ['example3'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts new file mode 100644 index 0000000000000..58bca149f56c1 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function historyWindowStartField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "history_window_start" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + history_window_start: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-1h', + target_version: 'now-30m', + merged_version: 'now-30m', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-1h', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-2h', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-30m', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + history_window_start: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + history_window_start: { + current_version: 'now-2h', + target_version: 'now-30m', + merged_version: 'now-30m', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts new file mode 100644 index 0000000000000..edaa6449a1d4e --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts @@ -0,0 +1,112 @@ +/* + * 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 { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; +import { nameField } from './name'; +import { descriptionField } from './description'; +import { tagsField } from './tags'; +import { severityField } from './severity'; +import { severityMappingField } from './severity_mapping'; +import { riskScoreField } from './risk_score'; +import { riskScoreMappingField } from './risk_score_mapping'; +import { referencesField } from './references'; +import { falsePositivesField } from './false_positives'; +import { threatField } from './threat'; +import { noteField } from './note'; +import { setupField } from './setup'; +import { relatedIntegrationsField } from './related_integrations'; +import { requiredFieldsField } from './required_fields'; +import { ruleScheduleField } from './rule_schedule'; +import { maxSignalsField } from './max_signals'; +import { ruleNameOverrideField } from './rule_name_override'; +import { timestampOverrideField } from './timestamp_override'; +import { timelineTemplateField } from './timeline_template'; +import { buildingBlockField } from './building_block'; +import { investigationFieldsField } from './investigation_fields'; +import { dataSourceField } from './data_source'; +import { alertSuppressionField } from './alert_suppression'; +import { inlineQueryKqlQueryField } from './kql_query.inline_query'; +import { savedQueryKqlQueryField } from './kql_query.saved_query'; +import { eqlQueryField } from './eql_query'; +import { esqlQueryField } from './esql_query'; +import { threatIndexField } from './threat_index'; +import { threatQueryField } from './threat_query'; +import { threatMappingField } from './threat_mapping'; +import { threatIndicatorPathField } from './threat_indicator_path'; +import { thresholdField } from './threshold'; +import { machineLearningJobIdField } from './machine_learning_job_id'; +import { anomalyThresholdField } from './anomaly_threshold'; +import { newTermsFieldsField } from './new_terms_fields'; +import { historyWindowStartField } from './history_window_start'; + +export default (context: FtrProviderContext): void => { + const es = context.getService('es'); + const supertest = context.getService('supertest'); + const log = context.getService('log'); + + describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + // Common fields + nameField(context); + descriptionField(context); + tagsField(context); + severityField(context); + severityMappingField(context); + riskScoreField(context); + riskScoreMappingField(context); + referencesField(context); + falsePositivesField(context); + threatField(context); + noteField(context); + setupField(context); + relatedIntegrationsField(context); + requiredFieldsField(context); + ruleScheduleField(context); + maxSignalsField(context); + ruleNameOverrideField(context); + timestampOverrideField(context); + timelineTemplateField(context); + buildingBlockField(context); + investigationFieldsField(context); + dataSourceField(context); + alertSuppressionField(context); + + // Custom Query, Threat Match, Threshold, New Terms rule types + inlineQueryKqlQueryField(context); + + // Saved Query rule types + savedQueryKqlQueryField(context); + + // EQL rule type + eqlQueryField(context); + + // ES|QL rule type + esqlQueryField(context); + + // Threat Match rule type + threatIndexField(context); + threatQueryField(context); + threatMappingField(context); + threatIndicatorPathField(context); + thresholdField(context); + + // Machine Learning rule type + machineLearningJobIdField(context); + anomalyThresholdField(context); + + // New Terms rule type + newTermsFieldsField(context); + historyWindowStartField(context); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts new file mode 100644 index 0000000000000..90a360ebaf887 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function investigationFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "investigation_fields" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + investigation_fields: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldA'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldA'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldC'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + investigation_fields: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldC'] }, + merged_version: { field_names: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts new file mode 100644 index 0000000000000..fdaf637c4f959 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts @@ -0,0 +1,450 @@ +/* + * 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 expect from 'expect'; +import { + KqlQueryType, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +const RULE_TYPES = ['query', 'threat_match', /* 'threshold',*/ 'new_terms'] as const; + +export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + for (const ruleType of RULE_TYPES) { + describe(`preview rule upgrade for "kql_query" field with inline query for "${ruleType}" rule type`, () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: '*:*', + language: 'kuery', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: 'process.name:*.sys', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); + } +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts new file mode 100644 index 0000000000000..ab8b74d13ae29 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts @@ -0,0 +1,374 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "kql_query" field with saved query', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id1', + }, + target_version: { + saved_query_id: 'saved_query_id2', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id1', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id2', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id3', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + kql_query: { + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id3', + }, + merged_version: { + saved_query_id: 'saved_query_id3', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts new file mode 100644 index 0000000000000..303f06bb86271 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function machineLearningJobIdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "machine_learning_job_id" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + machine_learning_job_id: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobA'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobA'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobC'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + machine_learning_job_id: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + current_version: ['jobB'], + target_version: ['jobC'], + merged_version: ['jobC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts new file mode 100644 index 0000000000000..0f4cf298cdd97 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function maxSignalsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "max_signals" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 100, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + max_signals: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 100, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 100, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 100, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 130, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 130, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 150, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 130, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + max_signals: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + max_signals: { + current_version: 130, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts new file mode 100644 index 0000000000000..4d0c9cac008fb --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function nameField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "name" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Original name', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + name: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Original name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Original name', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Original name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Updated name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Updated name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + name: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + name: { + current_version: 'Customized name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts new file mode 100644 index 0000000000000..805ecef23dd60 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function newTermsFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "new_terms_fields" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + new_terms_fields: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldA'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA', 'fieldC'], + merged_version: ['fieldB', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + new_terms_fields: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + current_version: ['fieldB'], + target_version: ['fieldA', 'fieldC'], + merged_version: ['fieldA', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts new file mode 100644 index 0000000000000..cde493b0b0040 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts @@ -0,0 +1,377 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function noteField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "note" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'some note', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + note: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'some note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'some note', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'customized note', + target_version: 'some note', + merged_version: 'customized note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'updated note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'line 1\nline 2', + }, + patch: { + note: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + note: 'line 1\nline 3', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'customized note', + target_version: 'updated note', + merged_version: 'customized note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + note: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + note: { + current_version: 'customized note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts new file mode 100644 index 0000000000000..be9859c82d7d1 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function referencesField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "references" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + references: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-2'], + target_version: ['http://url-1'], + merged_version: ['http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-1', 'http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1', 'http://url-2'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-3'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-2'], + target_version: ['http://url-1', 'http://url-3'], + merged_version: ['http://url-2', 'http://url-3'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + references: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-3'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + references: { + current_version: ['http://url-3'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts new file mode 100644 index 0000000000000..fc2b7cd8377e7 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts @@ -0,0 +1,553 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function relatedIntegrationsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "related_integrations" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + related_integrations: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + related_integrations: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + related_integrations: { + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts new file mode 100644 index 0000000000000..383563f507b92 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts @@ -0,0 +1,545 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function requiredFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "required_fields" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + required_fields: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + required_fields: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + required_fields: { + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts new file mode 100644 index 0000000000000..a696eaaf535ff --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function riskScoreField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "risk_score" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 10, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + risk_score: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 10, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 10, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 10, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 50, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 50, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 30, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 30, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + risk_score: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score: { + current_version: 50, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts new file mode 100644 index 0000000000000..9ed727a136f01 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts @@ -0,0 +1,597 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function riskScoreMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "risk_score_mapping" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + risk_score_mapping: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + risk_score_mapping: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + merged_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts new file mode 100644 index 0000000000000..d711326df4587 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function ruleNameOverrideField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "rule_name_override" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + rule_name_override: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldA' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldA' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldC' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + rule_name_override: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldC' }, + merged_version: { field_name: 'fieldC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts new file mode 100644 index 0000000000000..f4aa2349a23d4 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts @@ -0,0 +1,435 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function ruleScheduleField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "rule_schedule" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + rule_schedule: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', + to: 'now', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', + to: 'now', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + rule_schedule: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts new file mode 100644 index 0000000000000..0b348f2bc4814 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts @@ -0,0 +1,377 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function setupField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "setup" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + setup: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'some setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'customized setup', + target_version: 'some setup', + merged_version: 'customized setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'updated setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'line 1\nline 2', + }, + patch: { + setup: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + setup: 'line 1\nline 3', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'customized setup', + target_version: 'updated setup', + merged_version: 'customized setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + setup: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + setup: { + current_version: 'customized setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts new file mode 100644 index 0000000000000..c5c6283696723 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts @@ -0,0 +1,333 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function severityField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "severity" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: {}, + upgrade: { + type: 'query', + severity: 'low', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + severity: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'low', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'low', + target_version: 'high', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'low', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'low', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'medium', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'medium', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'high', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'medium', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + severity: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity: { + current_version: 'medium', + target_version: 'high', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts new file mode 100644 index 0000000000000..cfd8dafb7767f --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts @@ -0,0 +1,597 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function severityMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "severity_mapping" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + severity_mapping: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + severity_mapping: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + merged_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts new file mode 100644 index 0000000000000..81d8948333dd1 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function tagsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "tags" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + tags: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagA'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagA'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagC'], + merged_version: ['tagB', 'tagC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + tags: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + tags: { + current_version: ['tagB'], + target_version: ['tagC'], + merged_version: ['tagC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts new file mode 100644 index 0000000000000..84a8531633c8f --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts @@ -0,0 +1,673 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threat" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat: { + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts new file mode 100644 index 0000000000000..3bfea17373635 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatIndexField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threat_index" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_index: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexA'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexA'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexD'], + target_version: ['indexB', 'indexC'], + merged_version: ['indexD', 'indexB', 'indexC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexD'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_index: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_index: { + current_version: ['indexD'], + target_version: ['indexB', 'indexC'], + merged_version: ['indexB', 'indexC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts new file mode 100644 index 0000000000000..b727d472f722a --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatIndicatorPathField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threat_indicator_path" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_indicator_path: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldA', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldA', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldC', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_indicator_path: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + current_version: 'fieldB', + target_version: 'fieldC', + merged_version: 'fieldC', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts new file mode 100644 index 0000000000000..952a06a54c3fc --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts @@ -0,0 +1,348 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threat_mapping" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_mapping: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_mapping: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts new file mode 100644 index 0000000000000..8ff15200ab8ce --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts @@ -0,0 +1,432 @@ +/* + * 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 expect from 'expect'; +import { + KqlQueryType, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threat_query" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_query: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threat_query: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threat_query: { + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts new file mode 100644 index 0000000000000..8dc9ba752167e --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts @@ -0,0 +1,336 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function thresholdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "threshold" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threshold: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldA'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldA'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldC'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + threshold: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + threshold: { + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldC'] }, + merged_version: { value: 10, field: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts new file mode 100644 index 0000000000000..0fd82df3e8f09 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts @@ -0,0 +1,350 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function timelineTemplateField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "timeline_template" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + timeline_template: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + timeline_template: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timeline_template: { + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts new file mode 100644 index 0000000000000..94f285cbf3485 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts @@ -0,0 +1,331 @@ +/* + * 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 expect from 'expect'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function timestampOverrideField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('preview rule upgrade for "timestamp_override" field', () => { + it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + timestamp_override: expect.anything(), + }); + }); + + it('returns non-customized field with an upgrade (AAB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldA', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('returns customized field without an upgrade (ABA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldA', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with a matching upgrade (ABB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldC', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + describe('without historical versions', () => { + it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ + timestamp_override: expect.anything(), + }); + }); + + it('returns customized field with an matching upgrade (-AB diff case)', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(reviewResponse.rules).toHaveLength(1); + expect(reviewResponse.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(reviewResponse.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldC', fallback_disabled: false }, + merged_version: { field_name: 'fieldC', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts index 099ea907ef147..0333d41f522ee 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -16,6 +16,7 @@ import { } from './create_prebuilt_rule_saved_objects'; import { patchRule } from '../patch_rule'; import { installPrebuiltRules } from './install_prebuilt_rules'; +import { deleteAllPrebuiltRuleAssets } from './delete_all_prebuilt_rule_assets'; interface SetUpRuleUpgradeDeps { supertest: SuperTest.Agent; @@ -33,10 +34,15 @@ interface RuleUpgradeAssets { interface SetUpRuleUpgradeParams { assets: RuleUpgradeAssets; + removeInstalledAssets?: boolean; deps: SetUpRuleUpgradeDeps; } -export async function setUpRuleUpgrade({ assets, deps }: SetUpRuleUpgradeParams): Promise { +export async function setUpRuleUpgrade({ + assets, + removeInstalledAssets, + deps, +}: SetUpRuleUpgradeParams): Promise { await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(assets.installed.type, { rule_id: 'rule-1', @@ -50,6 +56,10 @@ export async function setUpRuleUpgrade({ assets, deps }: SetUpRuleUpgradeParams) ...assets.patch, }); + if (removeInstalledAssets) { + await deleteAllPrebuiltRuleAssets(deps.es, deps.log); + } + await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(assets.upgrade.type, { rule_id: 'rule-1', From 5fa7789f511a7145e1d8515a458cc606b53eafea Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 29 Jan 2025 14:53:27 +0100 Subject: [PATCH 03/20] add upgrade all rules integration tests --- .../upgrade_prebuilt_rules/index.ts | 27 + .../upgrade_all_rules.ts | 1175 +++++++++++++++++ .../prebuilt_rules/set_up_rule_upgrade.ts | 11 +- 3 files changed, 1209 insertions(+), 4 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts new file mode 100644 index 0000000000000..b547b9244a788 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts @@ -0,0 +1,27 @@ +/* + * 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 { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; +import { upgradeAllRules } from './upgrade_all_rules'; + +export default (context: FtrProviderContext): void => { + const es = context.getService('es'); + const supertest = context.getService('supertest'); + const log = context.getService('log'); + + describe('@ess @serverless @skipInServerlessMKI upgrade prebuilt rules', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + upgradeAllRules(context); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts new file mode 100644 index 0000000000000..2a2b89dd5f9f3 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts @@ -0,0 +1,1175 @@ +/* + * 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 expect from 'expect'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules } from '../../../../../utils'; + +export function upgradeAllRules({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + const deps = { + es, + supertest, + log, + }; + + const ruleFields = [ + QUERY_RULE_FIELDS, + SAVED_QUERY_RULE_FIELDS, + EQL_RULE_FIELDS, + ESQL_RULE_FIELDS, + THREAT_MATCH_RULE_FIELDS, + THRESHOLD_RULE_FIELDS, + ML_RULE_FIELDS, + NEW_TERMS_RULE_FIELDS, + ]; + + describe('(mode ALL_RULES)', () => { + for (const { versionA: fieldsVersionA, versionB: fieldsVersionB } of ruleFields) { + describe(`rule type "${fieldsVersionA.type}"`, () => { + it('upgrades all upgreadeable rule fields to their BASE versions', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + ...fieldsVersionA, + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + ...fieldsVersionB, + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'BASE', + }); + const upgradedRule = await securitySolutionApi.readRule({ query: { rule_id: 'rule_1' } }); + + expect(response.results.updated).toEqual([ + expect.objectContaining({ + ...fieldsVersionA, + rule_id: 'rule_1', + version: 2, + }), + ]); + expect(upgradedRule.body).toMatchObject({ + ...fieldsVersionA, + rule_id: 'rule_1', + version: 2, + }); + }); + + it('upgrades all upgreadeable rule fields to their TARGET versions', async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + ...fieldsVersionA, + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + ...fieldsVersionB, + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'TARGET', + }); + const upgradedRule = await securitySolutionApi.readRule({ query: { rule_id: 'rule_1' } }); + + expect(response.results.updated).toMatchObject([ + expect.objectContaining({ + ...fieldsVersionB, + rule_id: 'rule_1', + version: 2, + }), + ]); + expect(upgradedRule.body).toMatchObject({ + ...fieldsVersionB, + rule_id: 'rule_1', + version: 2, + }); + }); + }); + } + }); +} + +const QUERY_RULE_FIELDS = { + versionA: { + type: 'query' as const, + name: 'Custom query rule name', + description: 'Custom query rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { group_by: ['fieldA'] }, + query: 'process.name:*.exe', + language: 'kuery' as const, + }, + versionB: { + type: 'query' as const, + name: 'Updated custom query rule name', + description: 'Updated custom query rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { group_by: ['fieldB'] }, + query: 'process.name:*.sys', + language: 'kuery' as const, + }, +}; + +const SAVED_QUERY_RULE_FIELDS = { + versionA: { + type: 'saved_query' as const, + name: 'Saved query rule name', + description: 'Saved query rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { group_by: ['fieldA'] }, + saved_id: 'saved_query_idA', + }, + versionB: { + type: 'saved_query' as const, + name: 'Updated saved query rule name', + description: 'Updated saved query rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { group_by: ['fieldB'] }, + saved_id: 'saved_query_idB', + }, +}; + +const EQL_RULE_FIELDS = { + versionA: { + type: 'eql' as const, + name: 'EQL rule name', + description: 'EQL rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { group_by: ['fieldA'] }, + query: 'any where true', + }, + versionB: { + type: 'eql' as const, + name: 'Updated eql rule name', + description: 'Updated eql rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { group_by: ['fieldB'] }, + query: 'process where process.name == "regsvr32.exe"', + }, +}; + +const ESQL_RULE_FIELDS = { + versionA: { + type: 'esql' as const, + name: 'Esql rule name', + description: 'Esql rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + alert_suppression: { group_by: ['fieldA'] }, + query: 'FROM indexA METADATA _id', + language: 'esql' as const, + }, + versionB: { + type: 'esql' as const, + name: 'Updated esql rule name', + description: 'Updated esql rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + alert_suppression: { group_by: ['fieldB'] }, + query: 'FROM indexB METADATA _id', + language: 'esql' as const, + }, +}; + +const THREAT_MATCH_RULE_FIELDS = { + versionA: { + type: 'threat_match' as const, + name: 'Threat match rule name', + description: 'Threat match rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { group_by: ['fieldA'] }, + threat_index: ['indexA'], + threat_query: 'process.name:*.exe', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' } as const] }], + threat_indicator_path: 'fieldA', + }, + versionB: { + type: 'threat_match' as const, + name: 'Updated threat match rule name', + description: 'Updated threat match rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { group_by: ['fieldB'] }, + threat_index: ['indexB'], + threat_query: 'process.name:*.sys', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldY' } as const] }], + threat_indicator_path: 'fieldB', + }, +}; + +const THRESHOLD_RULE_FIELDS = { + versionA: { + type: 'threshold' as const, + name: 'Threshold rule name', + description: 'Threshold rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { duration: { value: 2, unit: 'h' } as const }, + query: 'process.name:*.exe', + language: 'kuery' as const, + threshold: { value: 10, field: ['fieldA'] }, + }, + versionB: { + type: 'threshold' as const, + name: 'Updated threshold rule name', + description: 'Updated threshold rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { duration: { value: 2, unit: 'h' } as const }, + query: 'process.name:*.sys', + language: 'kuery' as const, + threshold: { value: 20, field: ['fieldB'] }, + }, +}; + +const ML_RULE_FIELDS = { + versionA: { + type: 'machine_learning' as const, + name: 'Machine learning rule name', + description: 'Machine learning rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + alert_suppression: { group_by: ['fieldA'] }, + machine_learning_job_id: ['jobA'], + anomaly_threshold: 10, + }, + versionB: { + type: 'machine_learning' as const, + name: 'Updated machine learning rule name', + description: 'Updated machine learning rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + alert_suppression: { group_by: ['fieldB'] }, + machine_learning_job_id: ['jobB'], + anomaly_threshold: 20, + }, +}; + +const NEW_TERMS_RULE_FIELDS = { + versionA: { + type: 'new_terms' as const, + name: 'New terms rule name', + description: 'New terms rule description', + tags: ['tagA'], + severity: 'low' as const, + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + } as const, + ], + risk_score: 10, + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + } as const, + ], + references: ['http://url-1'], + false_positives: ['example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + note: 'Note 1', + setup: 'Setup 1', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + interval: '5m', + from: 'now-10m', + to: 'now', + max_signals: 100, + rule_name_override: 'fieldA', + timestamp_override: 'fieldA', + timeline_id: 'A', + timeline_title: 'timelineA', + building_block_type: 'default', + investigation_fields: { field_names: ['fieldA'] }, + index: ['indexA'], + alert_suppression: { group_by: ['fieldA'] }, + query: 'process.name:*.exe', + language: 'kuery' as const, + new_terms_fields: ['fieldA'], + history_window_start: 'now-1h', + }, + versionB: { + type: 'new_terms' as const, + name: 'Updated new terms rule name', + description: 'Updated new terms rule description', + tags: ['tagB'], + severity: 'medium' as const, + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '20', + } as const, + ], + risk_score: 20, + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '20', + risk_score: 20, + } as const, + ], + references: ['http://updated-url-1'], + false_positives: ['updated-example1'], + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + note: 'Updated note 1', + setup: 'Updated setup 1', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + interval: '10m', + from: 'now-20m', + to: 'now', + max_signals: 200, + rule_name_override: 'fieldB', + timestamp_override: 'fieldB', + timeline_id: 'B', + timeline_title: 'timelineB', + investigation_fields: { field_names: ['fieldB'] }, + index: ['indexB'], + alert_suppression: { group_by: ['fieldB'] }, + query: 'process.name:*.sys', + language: 'kuery' as const, + new_terms_fields: ['fieldB'], + history_window_start: 'now-2h', + }, +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts index 0333d41f522ee..fac636468322b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -51,10 +51,13 @@ export async function setUpRuleUpgrade({ }), ]); await installPrebuiltRules(deps.es, deps.supertest); - await patchRule(deps.supertest, deps.log, { - rule_id: 'rule-1', - ...assets.patch, - }); + + if (Object.keys(assets.patch).length > 0) { + await patchRule(deps.supertest, deps.log, { + rule_id: 'rule-1', + ...assets.patch, + }); + } if (removeInstalledAssets) { await deleteAllPrebuiltRuleAssets(deps.es, deps.log); From 2e59b610cf84eda6fe2bb1fe48ab23f7ed809c22 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 30 Jan 2025 16:13:46 +0100 Subject: [PATCH 04/20] refactor rule upgrade tests --- .../upgrade_prebuilt_rules.ts | 279 ---- .../bulk_upgrade_all_prebuilt_rules.ts | 368 ++++++ .../bulk_upgrade_selected_prebuilt_rules.ts | 454 +++++++ .../upgrade_prebuilt_rules/index.ts | 8 +- .../upgrade_all_rules.ts | 1175 ----------------- .../upgrade_one_prebuilt_rule.ts | 368 ++++++ ...prebuilt_rules_with_historical_versions.ts | 158 --- ...e_perform_prebuilt_rules.all_rules_mode.ts | 533 -------- ...form_prebuilt_rules.specific_rules_mode.ts | 865 ------------ .../utils/rules/patch_rule.ts | 2 +- .../prebuilt_rules/set_up_rule_upgrade.ts | 49 +- 11 files changed, 1226 insertions(+), 3033 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.all_rules_mode.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.specific_rules_mode.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts deleted file mode 100644 index a23ddf40979f6..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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 expect from 'expect'; -import { PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID } from '../../../../../../config/shared'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - createPrebuiltRuleAssetSavedObjects, - installPrebuiltRulesAndTimelines, - getPrebuiltRulesAndTimelinesStatus, - getPrebuiltRulesStatus, - installPrebuiltRules, - performUpgradePrebuiltRules, - fetchRule, - patchRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI upgrade prebuilt rules from package without historical versions with mock rule assets', () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-3', version: 3 }), - createRuleAssetSavedObject({ rule_id: 'rule-4', version: 4 }), - ]; - - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe('using legacy endpoint', () => { - it('should upgrade outdated prebuilt rules', async () => { - // Install all prebuilt detection rules - const ruleAssetSavedObjects = getRuleAssetSavedObjects(); - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Increment the version of one of the installed rules and create the new rule assets - ruleAssetSavedObjects[0]['security-rule'].version += 1; - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - }); - - it('should not upgrade prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_installed).toBe(0); - expect(statusResponse.rules_not_updated).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(0); - }); - }); - - describe('using current endpoint', () => { - it('should upgrade outdated prebuilt rules', async () => { - // Install all prebuilt detection rules - const ruleAssetSavedObjects = getRuleAssetSavedObjects(); - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Increment the version of one of the installed rules and create the new rule assets - ruleAssetSavedObjects[0]['security-rule'].version += 1; - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.skipped).toBe(0); - }); - - it('should not upgrade prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const installResponse = await installPrebuiltRules(es, supertest); - expect(installResponse.summary.succeeded).toBe(0); - expect(installResponse.summary.skipped).toBe(0); - - // Call the upgrade prebuilt rules endpoint and check that no rules were updated - const upgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - expect(upgradeResponse.summary.succeeded).toBe(0); - expect(upgradeResponse.summary.skipped).toBe(0); - }); - - describe('when upgrading a prebuilt rule to a newer version with the same rule type', () => { - it('preserves rule bound data', async () => { - await createPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-to-test-1', - enabled: true, - version: 1, - }), - ]); - const firstInstallResponse = await installPrebuiltRules(es, supertest); - const initialRuleSoId = firstInstallResponse.results.created[0].id; - - const actions = [ - // Use a preconfigured action connector to simplify the test and avoid action connector creation - { - id: PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID, - action_type_id: '.email', - group: 'default', - params: {}, - }, - ]; - const exceptionsList = [ - { - id: 'exception_list_1', - list_id: 'exception_list_1', - namespace_type: 'agnostic', - type: 'rule_default', - } as const, - ]; - - // Add some actions, exceptions list, and timeline reference - await patchRule(supertest, log, { - rule_id: 'rule-to-test-1', - enabled: false, - actions, - exceptions_list: exceptionsList, - timeline_id: 'some-timeline-id', - timeline_title: 'Some timeline title', - }); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Create a new version with the same rule type asset - await createPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-to-test-1', - enabled: true, - version: 2, - }), - ]); - - // Upgrade to a newer version with the same type - await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - - expect(await fetchRule(supertest, { ruleId: 'rule-to-test-1' })).toMatchObject({ - id: initialRuleSoId, - // If a user disabled the rule it's expected to stay disabled after upgrade - enabled: false, - actions, - exceptions_list: exceptionsList, - // current values for timeline_id and timeline_title are lost when updating to TARGET version - }); - }); - }); - - describe('when upgrading a prebuilt rule to a newer version with a different rule type', () => { - it('preserves rule bound data', async () => { - await createPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-to-test-2', - type: 'query', - language: 'kuery', - query: '*:*', - enabled: true, - version: 1, - }), - ]); - const firstInstallResponse = await installPrebuiltRules(es, supertest); - const initialRuleSoId = firstInstallResponse.results.created[0].id; - - const actions = [ - // Use a preconfigured action connector to simplify the test and avoid action connector creation - { - id: PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID, - action_type_id: '.email', - group: 'default', - params: {}, - }, - ]; - const exceptionsList = [ - { - id: 'exception_list_1', - list_id: 'exception_list_1', - namespace_type: 'agnostic', - type: 'rule_default', - } as const, - ]; - - // Add some actions, exceptions list, and timeline reference - await patchRule(supertest, log, { - rule_id: 'rule-to-test-2', - enabled: false, - actions, - exceptions_list: exceptionsList, - timeline_id: 'some-timeline-id', - timeline_title: 'Some timeline title', - }); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Create a new version with a different rule type asset - await createPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-to-test-2', - type: 'eql', - language: 'eql', - query: 'host where host == "something"', - enabled: true, - version: 2, - }), - ]); - - // Upgrade to a newer version with a different rule type - await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - - expect(await fetchRule(supertest, { ruleId: 'rule-to-test-2' })).toMatchObject({ - id: initialRuleSoId, - // If a user disabled the rule it's expected to stay disabled after upgrade - enabled: false, - actions, - exceptions_list: exceptionsList, - timeline_id: 'some-timeline-id', - timeline_title: 'Some timeline title', - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts new file mode 100644 index 0000000000000..2ed9de92ad6e0 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts @@ -0,0 +1,368 @@ +/* + * 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 expect from 'expect'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules } from '../../../../../utils'; + +export function bulkUpgradeAllPrebuiltRules({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const deps = { + es, + supertest, + log, + }; + + describe('all rules', () => { + describe('with historical versions', () => { + const TEST_DATA = [ + { pickVersion: 'BASE', expectedTags: ['tagA'] }, + { pickVersion: 'CURRENT', expectedTags: ['tagB'] }, + { pickVersion: 'TARGET', expectedTags: ['tagC'] }, + ] as const; + + for (const { pickVersion, expectedTags } of TEST_DATA) { + it(`upgrades to ${pickVersion} version`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: pickVersion, + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: expectedTags, + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: expectedTags, + }), + ]) + ); + }); + } + + it(`upgrades to TARGET version when is MERGED and there are no conflicts`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'MERGED', + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: ['tagC'], + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: ['tagC'], + }), + ]) + ); + }); + + it('DOES NOT upgrade in case of conflicts when is MERGED', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'MERGED', + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 0, + skipped: 0, + failed: 2, + }); + expect(response.errors).toHaveLength(2); + }); + }); + + describe('without historical versions', () => { + const TEST_DATA = [ + { pickVersion: 'CURRENT', expectedTags: ['tagB'] }, + { pickVersion: 'TARGET', expectedTags: ['tagC'] }, + ] as const; + + for (const { pickVersion, expectedTags } of TEST_DATA) { + it(`upgrades to ${pickVersion} version`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: pickVersion, + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: expectedTags, + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: expectedTags, + }), + ]) + ); + }); + } + + for (const pickVersion of ['BASE', 'MERGED'] as const) { + it(`UNABLE to upgrade to ${pickVersion} version`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: pickVersion, + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 0, + skipped: 0, + failed: 2, + }); + }); + } + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts new file mode 100644 index 0000000000000..0beb7d1074aed --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts @@ -0,0 +1,454 @@ +/* + * 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 expect from 'expect'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules } from '../../../../../utils'; + +export function bulkUpgradeSelectedPrebuiltRules({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const deps = { + es, + supertest, + log, + }; + + describe('selected rules', () => { + describe('with historical versions', () => { + const TEST_DATA = [ + { + globalPickVersion: 'BASE', + rulePickVersion: undefined, + expectedPickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: undefined, + expectedPickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: undefined, + expectedPickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'BASE', + expectedPickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'CURRENT', + expectedPickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'TARGET', + expectedPickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'BASE', + rulePickVersion: 'CURRENT', + expectedPickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + { + globalPickVersion: 'BASE', + rulePickVersion: 'TARGET', + expectedPickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: 'BASE', + expectedPickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: 'TARGET', + expectedPickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: 'BASE', + expectedPickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: 'CURRENT', + expectedPickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + ] as const; + + for (const { + globalPickVersion, + rulePickVersion, + expectedPickVersion, + expectedTags, + } of TEST_DATA) { + it(`upgrades to ${expectedPickVersion} version when "globalPickVersion: ${globalPickVersion}" and "rulePickVersion: ${rulePickVersion}"`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_3', + version: 1, + }, + patch: { + rule_id: 'rule_3', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_3', + version: 2, + }, + }, + ], + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + pick_version: globalPickVersion, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: rulePickVersion, + }, + { + rule_id: 'rule_2', + revision: 1, + version: 2, + pick_version: rulePickVersion, + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: expectedTags, + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: expectedTags, + }), + ]) + ); + }); + } + + it(`upgrades to TARGET when is MERGED and there are no conflicts`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_3', + version: 1, + }, + patch: { + rule_id: 'rule_3', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_3', + version: 2, + }, + }, + ], + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 0, + version: 2, + pick_version: 'MERGED', + }, + { + rule_id: 'rule_2', + revision: 0, + version: 2, + pick_version: 'MERGED', + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: ['tagC'], + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: ['tagC'], + }), + ]) + ); + }); + }); + + describe('without historical versions', () => { + const TEST_DATA = [ + { pickVersion: 'CURRENT', expectedTags: ['tagB'] }, + { pickVersion: 'TARGET', expectedTags: ['tagC'] }, + ] as const; + + for (const { pickVersion, expectedTags } of TEST_DATA) { + it(`upgrades to ${pickVersion} version`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: pickVersion, + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 1, + succeeded: 1, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toEqual([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: expectedTags, + }), + ]); + }); + } + + for (const pickVersion of ['BASE', 'MERGED'] as const) { + it(`UNABLE to upgrade to ${pickVersion} version`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: { + rule_id: 'rule_2', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: pickVersion, + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 1, + succeeded: 0, + skipped: 0, + failed: 1, + }); + }); + } + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts index b547b9244a788..b74ba80405e72 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts @@ -8,7 +8,9 @@ import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; -import { upgradeAllRules } from './upgrade_all_rules'; +import { bulkUpgradeAllPrebuiltRules } from './bulk_upgrade_all_prebuilt_rules'; +import { bulkUpgradeSelectedPrebuiltRules } from './bulk_upgrade_selected_prebuilt_rules'; +import { upgradeOnePrebuiltRule } from './upgrade_one_prebuilt_rule'; export default (context: FtrProviderContext): void => { const es = context.getService('es'); @@ -22,6 +24,8 @@ export default (context: FtrProviderContext): void => { await deleteAllPrebuiltRuleAssets(es, log); }); - upgradeAllRules(context); + bulkUpgradeAllPrebuiltRules(context); + bulkUpgradeSelectedPrebuiltRules(context); + upgradeOnePrebuiltRule(context); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts deleted file mode 100644 index 2a2b89dd5f9f3..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_all_rules.ts +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * 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 expect from 'expect'; -import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules } from '../../../../../utils'; - -export function upgradeAllRules({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - const deps = { - es, - supertest, - log, - }; - - const ruleFields = [ - QUERY_RULE_FIELDS, - SAVED_QUERY_RULE_FIELDS, - EQL_RULE_FIELDS, - ESQL_RULE_FIELDS, - THREAT_MATCH_RULE_FIELDS, - THRESHOLD_RULE_FIELDS, - ML_RULE_FIELDS, - NEW_TERMS_RULE_FIELDS, - ]; - - describe('(mode ALL_RULES)', () => { - for (const { versionA: fieldsVersionA, versionB: fieldsVersionB } of ruleFields) { - describe(`rule type "${fieldsVersionA.type}"`, () => { - it('upgrades all upgreadeable rule fields to their BASE versions', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - ...fieldsVersionA, - rule_id: 'rule_1', - version: 1, - }, - patch: {}, - upgrade: { - ...fieldsVersionB, - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'BASE', - }); - const upgradedRule = await securitySolutionApi.readRule({ query: { rule_id: 'rule_1' } }); - - expect(response.results.updated).toEqual([ - expect.objectContaining({ - ...fieldsVersionA, - rule_id: 'rule_1', - version: 2, - }), - ]); - expect(upgradedRule.body).toMatchObject({ - ...fieldsVersionA, - rule_id: 'rule_1', - version: 2, - }); - }); - - it('upgrades all upgreadeable rule fields to their TARGET versions', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - ...fieldsVersionA, - rule_id: 'rule_1', - version: 1, - }, - patch: {}, - upgrade: { - ...fieldsVersionB, - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'TARGET', - }); - const upgradedRule = await securitySolutionApi.readRule({ query: { rule_id: 'rule_1' } }); - - expect(response.results.updated).toMatchObject([ - expect.objectContaining({ - ...fieldsVersionB, - rule_id: 'rule_1', - version: 2, - }), - ]); - expect(upgradedRule.body).toMatchObject({ - ...fieldsVersionB, - rule_id: 'rule_1', - version: 2, - }); - }); - }); - } - }); -} - -const QUERY_RULE_FIELDS = { - versionA: { - type: 'query' as const, - name: 'Custom query rule name', - description: 'Custom query rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { group_by: ['fieldA'] }, - query: 'process.name:*.exe', - language: 'kuery' as const, - }, - versionB: { - type: 'query' as const, - name: 'Updated custom query rule name', - description: 'Updated custom query rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { group_by: ['fieldB'] }, - query: 'process.name:*.sys', - language: 'kuery' as const, - }, -}; - -const SAVED_QUERY_RULE_FIELDS = { - versionA: { - type: 'saved_query' as const, - name: 'Saved query rule name', - description: 'Saved query rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { group_by: ['fieldA'] }, - saved_id: 'saved_query_idA', - }, - versionB: { - type: 'saved_query' as const, - name: 'Updated saved query rule name', - description: 'Updated saved query rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { group_by: ['fieldB'] }, - saved_id: 'saved_query_idB', - }, -}; - -const EQL_RULE_FIELDS = { - versionA: { - type: 'eql' as const, - name: 'EQL rule name', - description: 'EQL rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { group_by: ['fieldA'] }, - query: 'any where true', - }, - versionB: { - type: 'eql' as const, - name: 'Updated eql rule name', - description: 'Updated eql rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { group_by: ['fieldB'] }, - query: 'process where process.name == "regsvr32.exe"', - }, -}; - -const ESQL_RULE_FIELDS = { - versionA: { - type: 'esql' as const, - name: 'Esql rule name', - description: 'Esql rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - alert_suppression: { group_by: ['fieldA'] }, - query: 'FROM indexA METADATA _id', - language: 'esql' as const, - }, - versionB: { - type: 'esql' as const, - name: 'Updated esql rule name', - description: 'Updated esql rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - alert_suppression: { group_by: ['fieldB'] }, - query: 'FROM indexB METADATA _id', - language: 'esql' as const, - }, -}; - -const THREAT_MATCH_RULE_FIELDS = { - versionA: { - type: 'threat_match' as const, - name: 'Threat match rule name', - description: 'Threat match rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { group_by: ['fieldA'] }, - threat_index: ['indexA'], - threat_query: 'process.name:*.exe', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' } as const] }], - threat_indicator_path: 'fieldA', - }, - versionB: { - type: 'threat_match' as const, - name: 'Updated threat match rule name', - description: 'Updated threat match rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { group_by: ['fieldB'] }, - threat_index: ['indexB'], - threat_query: 'process.name:*.sys', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldY' } as const] }], - threat_indicator_path: 'fieldB', - }, -}; - -const THRESHOLD_RULE_FIELDS = { - versionA: { - type: 'threshold' as const, - name: 'Threshold rule name', - description: 'Threshold rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { duration: { value: 2, unit: 'h' } as const }, - query: 'process.name:*.exe', - language: 'kuery' as const, - threshold: { value: 10, field: ['fieldA'] }, - }, - versionB: { - type: 'threshold' as const, - name: 'Updated threshold rule name', - description: 'Updated threshold rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { duration: { value: 2, unit: 'h' } as const }, - query: 'process.name:*.sys', - language: 'kuery' as const, - threshold: { value: 20, field: ['fieldB'] }, - }, -}; - -const ML_RULE_FIELDS = { - versionA: { - type: 'machine_learning' as const, - name: 'Machine learning rule name', - description: 'Machine learning rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - alert_suppression: { group_by: ['fieldA'] }, - machine_learning_job_id: ['jobA'], - anomaly_threshold: 10, - }, - versionB: { - type: 'machine_learning' as const, - name: 'Updated machine learning rule name', - description: 'Updated machine learning rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - alert_suppression: { group_by: ['fieldB'] }, - machine_learning_job_id: ['jobB'], - anomaly_threshold: 20, - }, -}; - -const NEW_TERMS_RULE_FIELDS = { - versionA: { - type: 'new_terms' as const, - name: 'New terms rule name', - description: 'New terms rule description', - tags: ['tagA'], - severity: 'low' as const, - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - } as const, - ], - risk_score: 10, - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - } as const, - ], - references: ['http://url-1'], - false_positives: ['example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - note: 'Note 1', - setup: 'Setup 1', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - interval: '5m', - from: 'now-10m', - to: 'now', - max_signals: 100, - rule_name_override: 'fieldA', - timestamp_override: 'fieldA', - timeline_id: 'A', - timeline_title: 'timelineA', - building_block_type: 'default', - investigation_fields: { field_names: ['fieldA'] }, - index: ['indexA'], - alert_suppression: { group_by: ['fieldA'] }, - query: 'process.name:*.exe', - language: 'kuery' as const, - new_terms_fields: ['fieldA'], - history_window_start: 'now-1h', - }, - versionB: { - type: 'new_terms' as const, - name: 'Updated new terms rule name', - description: 'Updated new terms rule description', - tags: ['tagB'], - severity: 'medium' as const, - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '20', - } as const, - ], - risk_score: 20, - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '20', - risk_score: 20, - } as const, - ], - references: ['http://updated-url-1'], - false_positives: ['updated-example1'], - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - note: 'Updated note 1', - setup: 'Updated setup 1', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - interval: '10m', - from: 'now-20m', - to: 'now', - max_signals: 200, - rule_name_override: 'fieldB', - timestamp_override: 'fieldB', - timeline_id: 'B', - timeline_title: 'timelineB', - investigation_fields: { field_names: ['fieldB'] }, - index: ['indexB'], - alert_suppression: { group_by: ['fieldB'] }, - query: 'process.name:*.sys', - language: 'kuery' as const, - new_terms_fields: ['fieldB'], - history_window_start: 'now-2h', - }, -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts new file mode 100644 index 0000000000000..7afc248628b80 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts @@ -0,0 +1,368 @@ +/* + * 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 expect from 'expect'; +import type SuperTest from 'supertest'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, getWebHookAction } from '../../../../../utils'; + +export function upgradeOnePrebuiltRule({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + const deps = { + es, + supertest, + log, + }; + + describe('one rule with historical version', () => { + const RULE_TYPES = [ + 'query', + 'saved_query', + 'eql', + 'esql', + 'threat_match', + 'threshold', + 'machine_learning', + 'new_terms', + ] as const; + + for (const ruleType of RULE_TYPES) { + it(`upgrades non-customized ${ruleType} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + name: 'Initial name', + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + type: ruleType, + name: 'Updated name', + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 0, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + + expect(response.results.updated).toMatchObject([ + { + rule_id: 'rule_1', + version: 2, + name: 'Updated name', + }, + ]); + }); + + it(`upgrades customized ${ruleType} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + name: 'Initial name', + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + name: 'Customized name', + }, + upgrade: { + type: ruleType, + name: 'Updated name', + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + + expect(response.results.updated).toMatchObject([ + { + rule_id: 'rule_1', + version: 2, + name: 'Updated name', + }, + ]); + }); + } + + const RULE_TYPE_CHANGES = RULE_TYPES.flatMap((ruleTypeA) => + RULE_TYPES.map((ruleTypeB) => [ruleTypeA, ruleTypeB] as const) + ).filter(([ruleTypeA, ruleTypeB]) => ruleTypeA !== ruleTypeB); + + for (const [ruleTypeA, ruleTypeB] of RULE_TYPE_CHANGES) { + it(`upgrades non-customized ${ruleTypeA} rule to ${ruleTypeB} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleTypeA, + name: 'Initial name', + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + type: ruleTypeB, + name: 'Updated name', + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 0, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + + expect(response.results.updated).toMatchObject([ + { + rule_id: 'rule_1', + version: 2, + type: ruleTypeB, + name: 'Updated name', + }, + ]); + }); + + it(`upgrades customized ${ruleTypeA} rule to ${ruleTypeB} rule type`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleTypeA, + name: 'Initial name', + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + name: 'Customized name', + }, + upgrade: { + type: ruleTypeB, + name: 'Updated name', + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + + expect(response.results.updated).toMatchObject([ + { + rule_id: 'rule_1', + version: 2, + type: ruleTypeB, + name: 'Updated name', + }, + ]); + }); + } + + for (const pickVersion of ['BASE', 'CURRENT', 'MERGED'] as const) { + it(`DOES NOT upgrade rule when rule type changed and is ${pickVersion}`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Initial name', + rule_id: 'rule_1', + version: 1, + }, + patch: { + rule_id: 'rule_1', + name: 'Customized name', + }, + upgrade: { + type: 'saved_query', + name: 'Updated name', + rule_id: 'rule_1', + version: 2, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: pickVersion, + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 1, + succeeded: 0, + skipped: 0, + failed: 1, + }); + expect(response.errors).toHaveLength(1); + }); + } + + for (const ruleType of RULE_TYPES) { + it(`DOES NOT upgrade non-upgradable fields for ${ruleType} rule`, async () => { + const NON_UPGRADABLE_FIELDS = { + enabled: true, + exceptions_list: [ + { + id: 'test-list', + list_id: 'test-list', + type: 'detection', + namespace_type: 'single', + } as const, + ], + actions: [await createAction(supertest)], + response_actions: [ + { + params: { + command: 'isolate' as const, + comment: 'comment', + }, + action_type_id: '.endpoint' as const, + }, + ], + meta: { some_key: 'some_value' }, + output_index: '.siem-signals-default', + namespace: 'default', + ...(ruleType === 'threat_match' ? { concurrent_searches: 5, items_per_search: 100 } : {}), + }; + + await setUpRuleUpgrade({ + assets: { + installed: { + rule_id: 'rule_1', + version: 1, + type: ruleType, + }, + patch: { + rule_id: 'rule_1', + type: ruleType, + ...NON_UPGRADABLE_FIELDS, + // Patch for Threshold rules fails without threshold specified + ...(ruleType === 'threshold' ? { threshold: { value: 10, field: 'fieldA' } } : {}), + }, + upgrade: { + rule_id: 'rule_1', + version: 2, + type: ruleType, + }, + }, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'TARGET', + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: 'rule_1' }, + }); + + expect(response.results.updated).toMatchObject([ + { + ...NON_UPGRADABLE_FIELDS, + version: 2, + }, + ]); + expect(upgradedRule.body).toMatchObject({ + ...NON_UPGRADABLE_FIELDS, + version: 2, + }); + }); + } + }); +} + +async function createAction(supertest: SuperTest.Agent) { + const createConnector = async (payload: Record) => + ( + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'true') + .send(payload) + .expect(200) + ).body; + + const createWebHookConnector = () => createConnector(getWebHookAction()); + + const webHookAction = await createWebHookConnector(); + + const defaultRuleAction = { + id: webHookAction.id, + action_type_id: '.webhook' as const, + group: 'default' as const, + params: { + body: '{"test":"a default action"}', + }, + frequency: { + notifyWhen: 'onThrottleInterval' as const, + summary: true, + throttle: '1h' as const, + }, + uuid: 'd487ec3d-05f2-44ad-8a68-11c97dc92202', + }; + + return defaultRuleAction; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts deleted file mode 100644 index 0eb37b1112f27..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 expect from 'expect'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRulesAndTimelines, - getPrebuiltRulesAndTimelinesStatus, - createHistoricalPrebuiltRuleAssetSavedObjects, - getPrebuiltRulesStatus, - installPrebuiltRules, - performUpgradePrebuiltRules, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI upgrade prebuilt rules from package with historical versions with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`rule package with historical versions`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 3 }), - ]; - - describe('using legacy endpoint', () => { - it('should upgrade outdated prebuilt rules when previous historical versions available', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Add a new version of one of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - - const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(_statusResponse.rules_not_installed).toBe(0); - expect(_statusResponse.rules_not_updated).toBe(0); - }); - - it('should upgrade outdated prebuilt rules when previous historical versions unavailable', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a new rule version - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - expect(statusResponse.rules_not_installed).toBe(0); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - - const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(_statusResponse.rules_not_updated).toBe(0); - expect(_statusResponse.rules_not_installed).toBe(0); - }); - }); - - describe('using current endpoint', () => { - it('should upgrade outdated prebuilt rules when previous historical versions available', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a new version of one of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that the prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - - // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.total).toBe(1); - - const status = await getPrebuiltRulesStatus(es, supertest); - expect(status.stats.num_prebuilt_rules_to_install).toBe(0); - expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); - }); - - it('should upgrade outdated prebuilt rules when previous historical versions unavailable', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a new rule version - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that the prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - - // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: 'ALL_RULES', - pick_version: 'TARGET', - }); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.total).toBe(1); - - const status = await getPrebuiltRulesStatus(es, supertest); - expect(status.stats.num_prebuilt_rules_to_install).toBe(0); - expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.all_rules_mode.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.all_rules_mode.ts deleted file mode 100644 index 9ee99df7a977a..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.all_rules_mode.ts +++ /dev/null @@ -1,533 +0,0 @@ -/* - * 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 expect from 'expect'; -import type SuperTest from 'supertest'; -import { cloneDeep } from 'lodash'; -import { - QueryRuleCreateFields, - EqlRuleCreateFields, - EsqlRuleCreateFields, - RuleResponse, - ThreatMatchRuleCreateFields, - ThreatMatchRule, - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION, - ModeEnum, - AllFieldsDiff, - DataSourceIndexPatterns, - QueryRule, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { PrebuiltRuleAsset } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObjectOfType, - installPrebuiltRules, - performUpgradePrebuiltRules, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - getInstalledRules, - createRuleAssetSavedObject, - getWebHookAction, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - describe('@ess @serverless @skipInServerlessMKI Perform Prebuilt Rules Upgrades - mode: ALL_RULES', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - const CURRENT_NAME = 'My current name'; - const CURRENT_TAGS = ['current', 'tags']; - const TARGET_NAME = 'My target name'; - const TARGET_TAGS = ['target', 'tags']; - - describe(`successful updates`, () => { - const queryRule = createRuleAssetSavedObjectOfType('query'); - const eqlRule = createRuleAssetSavedObjectOfType('eql'); - const esqlRule = createRuleAssetSavedObjectOfType('esql'); - - const basePrebuiltAssets = [queryRule, eqlRule, esqlRule]; - const basePrebuiltAssetsMap = createIdToRuleMap( - basePrebuiltAssets.map((r) => r['security-rule']) - ); - - const targetPrebuiltAssets = basePrebuiltAssets.map((ruleAssetSavedObject) => { - const targetObject = cloneDeep(ruleAssetSavedObject); - targetObject['security-rule'].version += 1; - targetObject['security-rule'].name = TARGET_NAME; - targetObject['security-rule'].tags = TARGET_TAGS; - - return targetObject; - }); - - it('upgrades all upgreadeable rules fields to their BASE versions', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - // Perform the upgrade, all rules' fields to their BASE versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'BASE', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(3); - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const matchingBaseAsset = basePrebuiltAssetsMap.get(updatedRule.rule_id); - if (!matchingBaseAsset) { - throw new Error(`Could not find matching base asset for rule ${updatedRule.rule_id}`); - } - - // Rule Version should be incremented by 1 - // Rule Name and Tags should match the base asset's values, not the Target asset's values - expect(updatedRule.version).toEqual(matchingBaseAsset.version + 1); - expect(updatedRule.name).toEqual(matchingBaseAsset.name); - expect(updatedRule.tags).toEqual(matchingBaseAsset.tags); - }); - - // Get installed rules - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - for (const [ruleId, installedRule] of installedRulesMap) { - const matchingBaseAsset = basePrebuiltAssetsMap.get(ruleId); - expect(installedRule.name).toEqual(matchingBaseAsset?.name); - expect(installedRule.tags).toEqual(matchingBaseAsset?.tags); - } - }); - - it('upgrades all upgreadeable rules fields to their CURRENT versions', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Patch all 3 installed rules to create a current version for each - for (const baseRule of basePrebuiltAssets) { - await patchRule(supertest, log, { - rule_id: baseRule['security-rule'].rule_id, - name: CURRENT_NAME, - tags: CURRENT_TAGS, - }); - } - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - // Perform the upgrade, all rules' fields to their CURRENT versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'CURRENT', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(3); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const matchingBaseAsset = basePrebuiltAssetsMap.get(updatedRule.rule_id); - // Rule Version should be incremented by 1 - // Rule Query should match the current's version query - if (matchingBaseAsset) { - expect(updatedRule.version).toEqual(matchingBaseAsset.version + 1); - expect(updatedRule.name).toEqual(CURRENT_NAME); - expect(updatedRule.tags).toEqual(CURRENT_TAGS); - } else { - throw new Error(`Matching base asset not found for rule_id: ${updatedRule.rule_id}`); - } - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - for (const [_, installedRule] of installedRulesMap) { - expect(installedRule.name).toEqual(CURRENT_NAME); - expect(installedRule.tags).toEqual(CURRENT_TAGS); - } - }); - - it('upgrades all upgreadeable rules fields to their TARGET versions', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Patch all 3 installed rules to create a current version for each - for (const baseRule of basePrebuiltAssets) { - await patchRule(supertest, log, { - rule_id: baseRule['security-rule'].rule_id, - query: CURRENT_NAME, - tags: CURRENT_TAGS, - }); - } - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - // Perform the upgrade, all rules' fields to their CURRENT versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'TARGET', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(3); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const matchingBaseAsset = basePrebuiltAssetsMap.get(updatedRule.rule_id); - - // Rule Version should be incremented by 1 - // Rule Query should match the current's version query - if (matchingBaseAsset) { - expect(updatedRule.version).toEqual(matchingBaseAsset.version + 1); - expect(updatedRule.name).toEqual(TARGET_NAME); - expect(updatedRule.tags).toEqual(TARGET_TAGS); - } else { - throw new Error(`Matching base asset not found for rule_id: ${updatedRule.rule_id}`); - } - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - for (const [_, installedRule] of installedRulesMap) { - expect(installedRule.name).toEqual(TARGET_NAME); - expect(installedRule.tags).toEqual(TARGET_TAGS); - } - }); - - it('upgrades all upgreadeable rules fields to their MERGED versions', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - // Call the /upgrade/_review endpoint to save the calculated merged_versions - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const reviewRuleResponseMap = new Map( - reviewResponse.rules.map((upgradeInfo) => [ - upgradeInfo.rule_id, - { - tags: upgradeInfo.diff.fields.tags?.merged_version, - name: upgradeInfo.diff.fields.name?.merged_version, - }, - ]) - ); - - // Perform the upgrade, all rules' fields to their MERGED versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'MERGED', - }); - const updatedRulesMap = createIdToRuleMap(performUpgradeResponse.results.updated); - - // All upgrades should succeed: neither query nor tags should have a merge conflict - expect(performUpgradeResponse.summary.succeeded).toEqual(3); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - for (const [ruleId, installedRule] of installedRulesMap) { - expect(installedRule.name).toEqual(updatedRulesMap.get(ruleId)?.name); - expect(installedRule.name).toEqual(reviewRuleResponseMap.get(ruleId)?.name); - expect(installedRule.tags).toEqual(updatedRulesMap.get(ruleId)?.tags); - expect(installedRule.tags).toEqual(reviewRuleResponseMap.get(ruleId)?.tags); - } - }); - - it('correctly upgrades rules with DataSource diffs to their MERGED versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [queryRule]); - await installPrebuiltRules(es, supertest); - - const targetObject = cloneDeep(queryRule); - targetObject['security-rule'].version += 1; - targetObject['security-rule'].name = TARGET_NAME; - targetObject['security-rule'].tags = TARGET_TAGS; - targetObject['security-rule'].index = ['auditbeat-*']; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetObject]); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const ruleDiffFields = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'MERGED', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data[0] as QueryRule; - - expect(installedRule.name).toEqual(ruleDiffFields.name.merged_version); - expect(installedRule.tags).toEqual(ruleDiffFields.tags.merged_version); - - // Check that the updated rules has an `index` field which equals the output of the diff algorithm - // for the DataSource diffable field, and that the data_view_id is correspondingly set to undefined. - expect(installedRule.index).toEqual( - (ruleDiffFields.data_source.merged_version as DataSourceIndexPatterns).index_patterns - ); - expect(installedRule.data_view_id).toBe(undefined); - }); - }); - - describe('edge cases and unhappy paths', () => { - const firstQueryRule = createRuleAssetSavedObject({ - type: 'query', - language: 'kuery', - rule_id: 'query-rule-1', - }); - const secondQueryRule = createRuleAssetSavedObject({ - type: 'query', - language: 'kuery', - rule_id: 'query-rule-2', - }); - const eqlRule = createRuleAssetSavedObject({ - type: 'eql', - language: 'eql', - rule_id: 'eql-rule', - }); - - const basePrebuiltAssets = [firstQueryRule, eqlRule, secondQueryRule]; - - it('rejects all updates of rules which have a rule type change if the pick_version is not TARGET', async () => { - // Install base prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Mock a rule type change to 'ml' to the first two rules of the basePrebuiltAssets array - const targetMLPrebuiltAssets = basePrebuiltAssets - .slice(0, 2) - .map((ruleAssetSavedObject) => { - const targetObject = cloneDeep(ruleAssetSavedObject); - - return { - ...targetObject, - ...createRuleAssetSavedObject({ - rule_id: targetObject['security-rule'].rule_id, - version: targetObject['security-rule'].version + 1, - type: 'machine_learning', - machine_learning_job_id: 'job_id', - anomaly_threshold: 1, - }), - }; - }); - - // Mock an normal update of the rule 'query-rule-2', with NO rule type change - const targetAssetSameTypeUpdate = createRuleAssetSavedObject({ - type: 'query', - language: 'kuery', - rule_id: 'query-rule-2', - version: 2, - }); - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - ...targetMLPrebuiltAssets, - targetAssetSameTypeUpdate, - ]); - - // Perform the upgrade, all rules' fields to their BASE versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'BASE', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); // update of same type - expect(performUpgradeResponse.summary.failed).toEqual(2); // updates with rule type change - - expect(performUpgradeResponse.errors).toHaveLength(2); - performUpgradeResponse.errors.forEach((error) => { - const ruleId = error.rules[0].rule_id; - expect(error.message).toContain( - `Rule update for rule ${ruleId} has a rule type change. All 'pick_version' values for rule must match 'TARGET'` - ); - }); - }); - - it('rejects updates of rules with a pick_version of MERGED which have fields which result in conflicts in the three way diff calculations', async () => { - // Install base prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - // Patch all 3 installed rules to create a current version for each - for (const baseRule of basePrebuiltAssets) { - await patchRule(supertest, log, { - rule_id: baseRule['security-rule'].rule_id, - name: CURRENT_NAME, - tags: CURRENT_TAGS, - }); - } - - const targetPrebuiltAssets = basePrebuiltAssets.map((ruleAssetSavedObject) => { - const targetObject = cloneDeep(ruleAssetSavedObject); - targetObject['security-rule'].version += 1; - targetObject['security-rule'].name = TARGET_NAME; - targetObject['security-rule'].tags = TARGET_TAGS; - - return targetObject; - }); - - // Create new versions of the assets of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - // Perform the upgrade, all rules' fields to their MERGED versions - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'MERGED', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(0); // all rules have conflicts - expect(performUpgradeResponse.summary.failed).toEqual(3); // all rules have conflicts - - performUpgradeResponse.errors.forEach((error) => { - const ruleId = error.rules[0].rule_id; - expect(error.message).toContain( - `Merge conflicts found in rule '${ruleId}' for fields: name, tags. Please resolve the conflict manually or choose another value for 'pick_version'` - ); - }); - }); - - it('preserves FIELDS_TO_UPGRADE_TO_CURRENT_VERSION when upgrading to TARGET version with undefined fields', async () => { - const baseRule = - createRuleAssetSavedObjectOfType('threat_match'); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [baseRule]); - await installPrebuiltRules(es, supertest); - - const ruleId = baseRule['security-rule'].rule_id; - - const installedBaseRule = ( - await securitySolutionApi.readRule({ - query: { - rule_id: ruleId, - }, - }) - ).body as ThreatMatchRule; - - // Patch the installed rule to set all FIELDS_TO_UPGRADE_TO_CURRENT_VERSION to some defined value - const currentValues: { [key: string]: unknown } = { - enabled: true, - exceptions_list: [ - { - id: 'test-list', - list_id: 'test-list', - type: 'detection', - namespace_type: 'single', - } as const, - ], - alert_suppression: { - group_by: ['host.name'], - duration: { value: 5, unit: 'm' as const }, - }, - actions: [await createAction(supertest)], - response_actions: [ - { - params: { - command: 'isolate' as const, - comment: 'comment', - }, - action_type_id: '.endpoint' as const, - }, - ], - meta: { some_key: 'some_value' }, - output_index: '.siem-signals-default', - namespace: 'default', - concurrent_searches: 5, - items_per_search: 100, - }; - - await securitySolutionApi.updateRule({ - body: { - ...installedBaseRule, - ...currentValues, - id: undefined, - }, - }); - - // Create a target version with undefined values for these fields - const targetRule = cloneDeep(baseRule); - targetRule['security-rule'].version += 1; - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - // @ts-expect-error - targetRule['security-rule'][field] = undefined; - }); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetRule]); - - // Perform the upgrade - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'TARGET', - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - const upgradedRule = performUpgradeResponse.results.updated[0] as ThreatMatchRule; - - // Check that all FIELDS_TO_UPGRADE_TO_CURRENT_VERSION still have their "current" values - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(upgradedRule[field]).toEqual(currentValues[field]); - }); - - // Verify the installed rule - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data.find( - (rule) => rule.rule_id === baseRule['security-rule'].rule_id - ) as ThreatMatchRule; - - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(installedRule[field]).toEqual(currentValues[field]); - }); - }); - }); - }); -}; - -function createIdToRuleMap(rules: Array) { - return new Map(rules.map((rule) => [rule.rule_id, rule])); -} - -async function createAction(supertest: SuperTest.Agent) { - const createConnector = async (payload: Record) => - ( - await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(payload) - .expect(200) - ).body; - - const createWebHookConnector = () => createConnector(getWebHookAction()); - - const webHookAction = await createWebHookConnector(); - - const defaultRuleAction = { - id: webHookAction.id, - action_type_id: '.webhook' as const, - group: 'default' as const, - params: { - body: '{"test":"a default action"}', - }, - frequency: { - notifyWhen: 'onThrottleInterval' as const, - summary: true, - throttle: '1h' as const, - }, - uuid: 'd487ec3d-05f2-44ad-8a68-11c97dc92202', - }; - - return defaultRuleAction; -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.specific_rules_mode.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.specific_rules_mode.ts deleted file mode 100644 index d3884b12808c5..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_perform_prebuilt_rules.specific_rules_mode.ts +++ /dev/null @@ -1,865 +0,0 @@ -/* - * 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 expect from 'expect'; -import type SuperTest from 'supertest'; -import { cloneDeep } from 'lodash'; -import { - QueryRuleCreateFields, - EqlRuleCreateFields, - EsqlRuleCreateFields, - ThreatMatchRuleCreateFields, - RuleResponse, - ModeEnum, - PickVersionValues, - RuleEqlQuery, - EqlRule, - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { PrebuiltRuleAsset } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules'; -import { ThreatMatchRule } from '@kbn/security-solution-plugin/common/api/detection_engine/model/rule_schema/rule_schemas.gen'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObjectOfType, - installPrebuiltRules, - performUpgradePrebuiltRules, - patchRule, - getInstalledRules, - createHistoricalPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - createRuleAssetSavedObject, - getWebHookAction, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - describe('@ess @serverless @skipInServerlessMKI Perform Prebuilt Rules Upgrades - mode: SPECIFIC_RULES', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - const CURRENT_NAME = 'My current name'; - const CURRENT_TAGS = ['current', 'tags']; - const TARGET_NAME = 'My target name'; - const TARGET_TAGS = ['target', 'tags']; - - describe('successful updates', () => { - const queryRule = createRuleAssetSavedObjectOfType('query'); - const eqlRule = createRuleAssetSavedObjectOfType('eql'); - const esqlRule = createRuleAssetSavedObjectOfType('esql'); - - const basePrebuiltAssets = [queryRule, eqlRule, esqlRule]; - - const targetPrebuiltAssets = basePrebuiltAssets.map((ruleAssetSavedObject) => { - const targetObject = cloneDeep(ruleAssetSavedObject); - targetObject['security-rule'].version += 1; - targetObject['security-rule'].name = TARGET_NAME; - targetObject['security-rule'].tags = TARGET_TAGS; - return targetObject; - }); - - it('upgrades specific rules to their BASE versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const rulesToUpgrade = basePrebuiltAssets.map((rule) => ({ - rule_id: rule['security-rule'].rule_id, - revision: 0, - version: rule['security-rule'].version + 1, - })); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'BASE', - rules: rulesToUpgrade, - }); - - const expectedResults = basePrebuiltAssets.map((asset) => ({ - rule_id: asset['security-rule'].rule_id, - version: asset['security-rule'].version + 1, - name: asset['security-rule'].name, - tags: asset['security-rule'].tags, - })); - - expect(performUpgradeResponse.summary.succeeded).toEqual(basePrebuiltAssets.length); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const expected = expectedResults.find((r) => r.rule_id === updatedRule.rule_id); - expect(updatedRule.version).toEqual(expected?.version); - expect(updatedRule.name).toEqual(expected?.name); - expect(updatedRule.tags).toEqual(expected?.tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - expectedResults.forEach((expected) => { - const installedRule = installedRulesMap.get(expected.rule_id); - expect(installedRule?.name).toEqual(expected.name); - expect(installedRule?.tags).toEqual(expected.tags); - }); - }); - - it('upgrades specific rules to their CURRENT versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - for (const baseRule of basePrebuiltAssets) { - await patchRule(supertest, log, { - rule_id: baseRule['security-rule'].rule_id, - name: CURRENT_NAME, - tags: CURRENT_TAGS, - }); - } - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const rulesToUpgrade = basePrebuiltAssets.map((rule) => ({ - rule_id: rule['security-rule'].rule_id, - revision: 1, - version: rule['security-rule'].version + 1, - })); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'CURRENT', - rules: rulesToUpgrade, - }); - - const expectedResults = basePrebuiltAssets.map((asset) => ({ - rule_id: asset['security-rule'].rule_id, - name: CURRENT_NAME, - tags: CURRENT_TAGS, - })); - - expect(performUpgradeResponse.summary.succeeded).toEqual(basePrebuiltAssets.length); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const expected = expectedResults.find((r) => r.rule_id === updatedRule.rule_id); - expect(updatedRule.name).toEqual(expected?.name); - expect(updatedRule.tags).toEqual(expected?.tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - expectedResults.forEach((expected) => { - const installedRule = installedRulesMap.get(expected.rule_id); - expect(installedRule?.name).toEqual(expected.name); - expect(installedRule?.tags).toEqual(expected.tags); - }); - }); - - it('upgrades specific rules to their TARGET versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const rulesToUpgrade = basePrebuiltAssets.map((rule) => ({ - rule_id: rule['security-rule'].rule_id, - revision: 0, - version: rule['security-rule'].version + 1, - })); - - const expectedResults = basePrebuiltAssets.map((asset) => ({ - rule_id: asset['security-rule'].rule_id, - name: TARGET_NAME, - tags: TARGET_TAGS, - })); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: rulesToUpgrade, - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(basePrebuiltAssets.length); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const expected = expectedResults.find((r) => r.rule_id === updatedRule.rule_id); - expect(updatedRule.name).toEqual(expected?.name); - expect(updatedRule.tags).toEqual(expected?.tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - expectedResults.forEach((expected) => { - const installedRule = installedRulesMap.get(expected.rule_id); - expect(installedRule?.name).toEqual(expected.name); - expect(installedRule?.tags).toEqual(expected.tags); - }); - }); - - it('upgrades specific rules to their MERGED versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const expectedResults = reviewResponse.rules.map((upgradeInfo) => ({ - rule_id: upgradeInfo.rule_id, - name: upgradeInfo.diff.fields.name?.merged_version, - tags: upgradeInfo.diff.fields.tags?.merged_version, - })); - - const rulesToUpgrade = basePrebuiltAssets.map((rule) => ({ - rule_id: rule['security-rule'].rule_id, - revision: 0, - version: rule['security-rule'].version + 1, - })); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'MERGED', - rules: rulesToUpgrade, - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(basePrebuiltAssets.length); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const expected = expectedResults.find((r) => r.rule_id === updatedRule.rule_id); - expect(updatedRule.name).toEqual(expected?.name); - expect(updatedRule.tags).toEqual(expected?.tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - expectedResults.forEach((expected) => { - const installedRule = installedRulesMap.get(expected.rule_id); - expect(installedRule?.name).toEqual(expected.name); - expect(installedRule?.tags).toEqual(expected.tags); - }); - }); - - it('upgrades specific rules to their TARGET versions but overrides some fields with `fields` in the request payload', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const rulesToUpgrade = basePrebuiltAssets.map((rule) => ({ - rule_id: rule['security-rule'].rule_id, - revision: 0, - version: rule['security-rule'].version + 1, - fields: { - name: { pick_version: 'BASE' as PickVersionValues }, - }, - })); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: rulesToUpgrade, - }); - - const expectedResults = basePrebuiltAssets.map((asset) => ({ - rule_id: asset['security-rule'].rule_id, - name: asset['security-rule'].name, - tags: TARGET_TAGS, - })); - - expect(performUpgradeResponse.summary.succeeded).toEqual(basePrebuiltAssets.length); - - performUpgradeResponse.results.updated.forEach((updatedRule) => { - const expected = expectedResults.find((r) => r.rule_id === updatedRule.rule_id); - expect(updatedRule.name).toEqual(expected?.name); - expect(updatedRule.tags).toEqual(expected?.tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - expectedResults.forEach((expected) => { - const installedRule = installedRulesMap.get(expected.rule_id); - expect(installedRule?.name).toEqual(expected.name); - expect(installedRule?.tags).toEqual(expected.tags); - }); - }); - - it('upgrades specific rules with different pick_version at global, rule, and field levels', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - for (const baseRule of basePrebuiltAssets) { - await patchRule(supertest, log, { - rule_id: baseRule['security-rule'].rule_id, - name: CURRENT_NAME, - tags: CURRENT_TAGS, - }); - } - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, targetPrebuiltAssets); - - const rulesToUpgrade = [ - { - rule_id: basePrebuiltAssets[0]['security-rule'].rule_id, - revision: 1, - version: basePrebuiltAssets[0]['security-rule'].version + 1, - pick_version: 'CURRENT' as PickVersionValues, - }, - { - rule_id: basePrebuiltAssets[1]['security-rule'].rule_id, - revision: 1, - version: basePrebuiltAssets[1]['security-rule'].version + 1, - fields: { - name: { pick_version: 'TARGET' as PickVersionValues }, - tags: { pick_version: 'BASE' as PickVersionValues }, - }, - }, - { - rule_id: basePrebuiltAssets[2]['security-rule'].rule_id, - revision: 1, - version: basePrebuiltAssets[2]['security-rule'].version + 1, - }, - ]; - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'BASE', - rules: rulesToUpgrade, - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(3); - const updatedRulesMap = createIdToRuleMap(performUpgradeResponse.results.updated); - - const expectedResults = [ - { name: CURRENT_NAME, tags: CURRENT_TAGS }, - { name: TARGET_NAME, tags: basePrebuiltAssets[1]['security-rule'].tags }, - { - name: basePrebuiltAssets[2]['security-rule'].name, - tags: basePrebuiltAssets[2]['security-rule'].tags, - }, - ]; - - basePrebuiltAssets.forEach((asset, index) => { - const ruleId = asset['security-rule'].rule_id; - const updatedRule = updatedRulesMap.get(ruleId); - expect(updatedRule?.name).toEqual(expectedResults[index].name); - expect(updatedRule?.tags).toEqual(expectedResults[index].tags); - }); - - const installedRules = await getInstalledRules(supertest); - const installedRulesMap = createIdToRuleMap(installedRules.data); - - basePrebuiltAssets.forEach((asset, index) => { - const ruleId = asset['security-rule'].rule_id; - const installedRule = installedRulesMap.get(ruleId); - expect(installedRule?.name).toEqual(expectedResults[index].name); - expect(installedRule?.tags).toEqual(expectedResults[index].tags); - }); - }); - - it('successfully resolves a non-resolvable conflict by using pick_version:RESOLVED for that field', async () => { - const baseEqlRule = createRuleAssetSavedObjectOfType('eql'); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [baseEqlRule]); - await installPrebuiltRules(es, supertest); - - // Patch the installed rule to edit its query - const patchedQuery = 'sequence by process.name [MY CURRENT QUERY]'; - await patchRule(supertest, log, { - rule_id: baseEqlRule['security-rule'].rule_id, - query: patchedQuery, - }); - - // Create a new version of the prebuilt rule asset with a different query and generate the conflict - const targetEqlRule = cloneDeep(baseEqlRule); - targetEqlRule['security-rule'].version += 1; - targetEqlRule['security-rule'].query = 'sequence by process.name [MY TARGET QUERY]'; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetEqlRule]); - - const resolvedValue = { - query: 'sequence by process.name [MY RESOLVED QUERY]', - language: 'eql', - filters: [], - }; - - // Perform the upgrade with manual conflict resolution - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'MERGED', - rules: [ - { - rule_id: baseEqlRule['security-rule'].rule_id, - revision: 1, - version: baseEqlRule['security-rule'].version + 1, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: resolvedValue as RuleEqlQuery, - }, - }, - }, - ], - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - const updatedRule = performUpgradeResponse.results.updated[0] as EqlRule; - expect(updatedRule.rule_id).toEqual(baseEqlRule['security-rule'].rule_id); - expect(updatedRule.query).toEqual(resolvedValue.query); - expect(updatedRule.filters).toEqual(resolvedValue.filters); - expect(updatedRule.language).toEqual(resolvedValue.language); - - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data.find( - (rule) => rule.rule_id === baseEqlRule['security-rule'].rule_id - ) as EqlRule; - expect(installedRule?.query).toEqual(resolvedValue.query); - expect(installedRule?.filters).toEqual(resolvedValue.filters); - expect(installedRule?.language).toEqual(resolvedValue.language); - }); - }); - - describe('edge cases and unhappy paths', () => { - const queryRule = createRuleAssetSavedObject({ - type: 'query', - language: 'kuery', - rule_id: 'query-rule', - }); - const eqlRule = createRuleAssetSavedObject({ - type: 'eql', - language: 'eql', - rule_id: 'eql-rule', - }); - - const basePrebuiltAssets = [queryRule, eqlRule]; - - it('rejects updates when rule type changes and pick_version is not TARGET at all levels', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - const targetMLRule = createRuleAssetSavedObject({ - rule_id: queryRule['security-rule'].rule_id, - version: queryRule['security-rule'].version + 1, - type: 'machine_learning', - machine_learning_job_id: 'job_id', - anomaly_threshold: 1, - }); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetMLRule]); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'BASE', - rules: [ - { - rule_id: queryRule['security-rule'].rule_id, - revision: 0, - version: queryRule['security-rule'].version + 1, - }, - ], - }); - - expect(performUpgradeResponse.summary.failed).toEqual(1); - expect(performUpgradeResponse.errors[0].message).toContain( - 'Rule update for rule query-rule has a rule type change' - ); - }); - - it('rejects updates when incompatible fields are provided for a rule type', async () => { - const baseEqlRule = createRuleAssetSavedObjectOfType('eql'); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [baseEqlRule]); - await installPrebuiltRules(es, supertest); - - // Create a new version of the prebuilt rule asset with a different query and generate the conflict - const targetEqlRule = cloneDeep(baseEqlRule); - targetEqlRule['security-rule'].version += 1; - targetEqlRule['security-rule'].query = 'sequence by process.name [MY TARGET QUERY]'; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetEqlRule]); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: [ - { - rule_id: baseEqlRule['security-rule'].rule_id, - revision: 0, - version: baseEqlRule['security-rule'].version + 1, - fields: { - machine_learning_job_id: { pick_version: 'TARGET' }, - }, - }, - ], - }); - - expect(performUpgradeResponse.summary.failed).toEqual(1); - expect(performUpgradeResponse.errors[0].message).toContain( - "machine_learning_job_id is not a valid upgradeable field for type 'eql'" - ); - }); - - it('rejects updates with NON_SOLVABLE conflicts when using MERGED pick_version', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - await patchRule(supertest, log, { - rule_id: queryRule['security-rule'].rule_id, - name: CURRENT_NAME, - }); - - const targetQueryRule = cloneDeep(queryRule); - targetQueryRule['security-rule'].version += 1; - targetQueryRule['security-rule'].name = TARGET_NAME; - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetQueryRule]); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'MERGED', - rules: [ - { - rule_id: queryRule['security-rule'].rule_id, - revision: 1, - version: queryRule['security-rule'].version + 1, - }, - ], - }); - - expect(performUpgradeResponse.summary.failed).toEqual(1); - expect(performUpgradeResponse.errors[0].message).toContain( - `Automatic merge calculation for field 'name' in rule of rule_id ${performUpgradeResponse.errors[0].rules[0].rule_id} resulted in a conflict. Please resolve the conflict manually or choose another value for 'pick_version'` - ); - }); - - it('allows updates with NON_SOLVABLE conflicts when specific fields have non-MERGED pick_version', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - await patchRule(supertest, log, { - rule_id: queryRule['security-rule'].rule_id, - name: CURRENT_NAME, - }); - - const targetQueryRule = cloneDeep(queryRule); - targetQueryRule['security-rule'].version += 1; - targetQueryRule['security-rule'].name = TARGET_NAME; - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetQueryRule]); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'MERGED', - rules: [ - { - rule_id: queryRule['security-rule'].rule_id, - revision: 1, - version: queryRule['security-rule'].version + 1, - fields: { - name: { pick_version: 'TARGET' }, - }, - }, - ], - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - expect(performUpgradeResponse.results.updated[0].name).toEqual(TARGET_NAME); - - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data.find( - (rule) => rule.rule_id === queryRule['security-rule'].rule_id - ); - expect(installedRule?.name).toEqual(TARGET_NAME); - }); - - it('rejects updates for specific fields with MERGED pick_version and NON_SOLVABLE conflicts', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, basePrebuiltAssets); - await installPrebuiltRules(es, supertest); - - await patchRule(supertest, log, { - rule_id: queryRule['security-rule'].rule_id, - name: CURRENT_NAME, - }); - - const targetQueryRule = cloneDeep(queryRule); - targetQueryRule['security-rule'].version += 1; - targetQueryRule['security-rule'].name = TARGET_NAME; - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetQueryRule]); - - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: [ - { - rule_id: queryRule['security-rule'].rule_id, - revision: 1, - version: queryRule['security-rule'].version + 1, - fields: { - name: { pick_version: 'MERGED' }, - }, - }, - ], - }); - - expect(performUpgradeResponse.summary.failed).toEqual(1); - expect(performUpgradeResponse.errors[0].message).toContain( - `Automatic merge calculation for field 'name' in rule of rule_id ${performUpgradeResponse.errors[0].rules[0].rule_id} resulted in a conflict. Please resolve the conflict manually or choose another value for 'pick_version'.` - ); - }); - - it('preserves FIELDS_TO_UPGRADE_TO_CURRENT_VERSION when upgrading to TARGET version with undefined fields', async () => { - const baseRule = - createRuleAssetSavedObjectOfType('threat_match'); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [baseRule]); - await installPrebuiltRules(es, supertest); - - const ruleId = baseRule['security-rule'].rule_id; - - const installedBaseRule = ( - await securitySolutionApi.readRule({ - query: { - rule_id: ruleId, - }, - }) - ).body as ThreatMatchRule; - - // Patch the installed rule to set all FIELDS_TO_UPGRADE_TO_CURRENT_VERSION to some defined value - const currentValues: { [key: string]: unknown } = { - enabled: true, - exceptions_list: [ - { - id: 'test-list', - list_id: 'test-list', - type: 'detection', - namespace_type: 'single', - } as const, - ], - alert_suppression: { - group_by: ['host.name'], - duration: { value: 5, unit: 'm' as const }, - }, - actions: [await createAction(supertest)], - response_actions: [ - { - params: { - command: 'isolate' as const, - comment: 'comment', - }, - action_type_id: '.endpoint' as const, - }, - ], - meta: { some_key: 'some_value' }, - output_index: '.siem-signals-default', - namespace: 'default', - concurrent_searches: 5, - items_per_search: 100, - }; - - await securitySolutionApi.updateRule({ - body: { - ...installedBaseRule, - ...currentValues, - id: undefined, - }, - }); - - // Create a target version with undefined values for these fields - const targetRule = cloneDeep(baseRule); - targetRule['security-rule'].version += 1; - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - // @ts-expect-error - targetRule['security-rule'][field] = undefined; - }); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetRule]); - - // Perform the upgrade - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: [ - { - rule_id: baseRule['security-rule'].rule_id, - revision: 1, - version: baseRule['security-rule'].version + 1, - }, - ], - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - const upgradedRule = performUpgradeResponse.results.updated[0] as ThreatMatchRule; - - // Check that all FIELDS_TO_UPGRADE_TO_CURRENT_VERSION still have their "current" values - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(upgradedRule[field]).toEqual(currentValues[field]); - }); - - // Verify the installed rule - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data.find( - (rule) => rule.rule_id === baseRule['security-rule'].rule_id - ) as ThreatMatchRule; - - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(installedRule[field]).toEqual(currentValues[field]); - }); - }); - - it('preserves FIELDS_TO_UPGRADE_TO_CURRENT_VERSION when fields are attempted to be updated via resolved values', async () => { - const baseRule = - createRuleAssetSavedObjectOfType('threat_match'); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [baseRule]); - await installPrebuiltRules(es, supertest); - - const ruleId = baseRule['security-rule'].rule_id; - - const installedBaseRule = ( - await securitySolutionApi.readRule({ - query: { - rule_id: ruleId, - }, - }) - ).body as ThreatMatchRule; - - // Set current values for FIELDS_TO_UPGRADE_TO_CURRENT_VERSION - const currentValues: { [key: string]: unknown } = { - enabled: true, - exceptions_list: [ - { - id: 'test-list', - list_id: 'test-list', - type: 'detection', - namespace_type: 'single', - } as const, - ], - alert_suppression: { - group_by: ['host.name'], - duration: { value: 5, unit: 'm' as const }, - }, - actions: [await createAction(supertest)], - response_actions: [ - { - params: { - command: 'isolate' as const, - comment: 'comment', - }, - action_type_id: '.endpoint' as const, - }, - ], - meta: { some_key: 'some_value' }, - output_index: '.siem-signals-default', - namespace: 'default', - concurrent_searches: 5, - items_per_search: 100, - }; - - await securitySolutionApi.updateRule({ - body: { - ...installedBaseRule, - ...currentValues, - id: undefined, - }, - }); - - // Create a target version with undefined values for these fields - const targetRule = cloneDeep(baseRule); - targetRule['security-rule'].version += 1; - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - // @ts-expect-error - targetRule['security-rule'][field] = undefined; - }); - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [targetRule]); - - // Create resolved values different from current values - const resolvedValues: { [key: string]: unknown } = { - alert_suppression: { - group_by: ['test'], - duration: { value: 10, unit: 'm' as const }, - }, - }; - - const fields = Object.fromEntries( - Object.keys(resolvedValues).map((field) => [ - field, - { - pick_version: 'RESOLVED' as PickVersionValues, - resolved_value: resolvedValues[field], - }, - ]) - ); - - // Perform the upgrade with resolved values - const performUpgradeResponse = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - pick_version: 'TARGET', - rules: [ - { - rule_id: baseRule['security-rule'].rule_id, - revision: 1, - version: baseRule['security-rule'].version + 1, - fields, - }, - ], - }); - - expect(performUpgradeResponse.summary.succeeded).toEqual(1); - const upgradedRule = performUpgradeResponse.results.updated[0] as ThreatMatchRule; - - // Check that all FIELDS_TO_UPGRADE_TO_CURRENT_VERSION still have their "current" values - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(upgradedRule[field]).toEqual(currentValues[field]); - }); - - // Verify the installed rule - const installedRules = await getInstalledRules(supertest); - const installedRule = installedRules.data.find( - (rule) => rule.rule_id === baseRule['security-rule'].rule_id - ) as ThreatMatchRule; - - FIELDS_TO_UPGRADE_TO_CURRENT_VERSION.forEach((field) => { - expect(installedRule[field]).toEqual(currentValues[field]); - }); - }); - }); - }); -}; - -function createIdToRuleMap(rules: Array) { - return new Map(rules.map((rule) => [rule.rule_id, rule])); -} - -async function createAction(supertest: SuperTest.Agent) { - const createConnector = async (payload: Record) => - ( - await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(payload) - .expect(200) - ).body; - - const createWebHookConnector = () => createConnector(getWebHookAction()); - - const webHookAction = await createWebHookConnector(); - - const defaultRuleAction = { - id: webHookAction.id, - action_type_id: '.webhook' as const, - group: 'default' as const, - params: { - body: '{"test":"a default action"}', - }, - frequency: { - notifyWhen: 'onThrottleInterval' as const, - summary: true, - throttle: '1h' as const, - }, - uuid: 'd487ec3d-05f2-44ad-8a68-11c97dc92202', - }; - - return defaultRuleAction; -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/patch_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/patch_rule.ts index 44456c93a16cd..18ef05a4090f7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/patch_rule.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/patch_rule.ts @@ -34,7 +34,7 @@ export const patchRule = async ( log.error( `Did not get an expected 200 "ok" when patching a rule (patchRule). CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify( response.body - )}, status: ${JSON.stringify(response.status)}` + )}, status: ${JSON.stringify(response.status)}, body: ${JSON.stringify(response.body)}` ); } return response.body; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts index fac636468322b..6233b0e057df2 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -33,7 +33,7 @@ interface RuleUpgradeAssets { } interface SetUpRuleUpgradeParams { - assets: RuleUpgradeAssets; + assets: RuleUpgradeAssets | RuleUpgradeAssets[]; removeInstalledAssets?: boolean; deps: SetUpRuleUpgradeDeps; } @@ -43,31 +43,40 @@ export async function setUpRuleUpgrade({ removeInstalledAssets, deps, }: SetUpRuleUpgradeParams): Promise { - await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ - createRuleAssetSavedObjectOfType(assets.installed.type, { - rule_id: 'rule-1', - version: 1, - ...assets.installed, - }), - ]); + const rulesAssets = [assets].flat(); + + for (const ruleAssets of rulesAssets) { + await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ + createRuleAssetSavedObjectOfType(ruleAssets.installed.type, { + rule_id: 'rule-1', + version: 1, + ...ruleAssets.installed, + }), + ]); + } + await installPrebuiltRules(deps.es, deps.supertest); - if (Object.keys(assets.patch).length > 0) { - await patchRule(deps.supertest, deps.log, { - rule_id: 'rule-1', - ...assets.patch, - }); + for (const ruleAssets of rulesAssets) { + if (Object.keys(ruleAssets.patch).length > 0) { + await patchRule(deps.supertest, deps.log, { + rule_id: 'rule-1', + ...ruleAssets.patch, + }); + } } if (removeInstalledAssets) { await deleteAllPrebuiltRuleAssets(deps.es, deps.log); } - await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ - createRuleAssetSavedObjectOfType(assets.upgrade.type, { - rule_id: 'rule-1', - version: 2, - ...assets.upgrade, - }), - ]); + for (const ruleAssets of rulesAssets) { + await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ + createRuleAssetSavedObjectOfType(ruleAssets.upgrade.type, { + rule_id: 'rule-1', + version: 2, + ...ruleAssets.upgrade, + }), + ]); + } } From d7881f676ede0485f07453aedeab7dc8f437a5ae Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 1 Feb 2025 13:43:57 +0100 Subject: [PATCH 05/20] extend diffable rule fields tests with upgrade workflow --- .../diffable_rule_fields/alert_suppression.ts | 655 ++++++++ .../diffable_rule_fields/anomaly_threshold.ts | 660 ++++++++ .../diffable_rule_fields/building_block.ts | 648 ++++++++ .../diffable_rule_fields/data_source.ts | 1332 +++++++++++++++++ .../diffable_rule_fields/description.ts | 663 ++++++++ .../diffable_rule_fields/eql_query.ts | 793 ++++++++++ .../diffable_rule_fields/esql_query.ts | 756 ++++++++++ .../diffable_rule_fields/false_positives.ts | 655 ++++++++ .../history_window_start.ts | 660 ++++++++ .../index.ts | 4 +- .../investigation_fields.ts | 655 ++++++++ .../kql_query.inline_query.ts | 837 +++++++++++ .../kql_query.saved_query.ts | 720 +++++++++ .../machine_learning_job_id.ts | 660 ++++++++ .../diffable_rule_fields/max_signals.ts | 655 ++++++++ .../diffable_rule_fields/name.ts | 655 ++++++++ .../diffable_rule_fields/new_terms_fields.ts | 660 ++++++++ .../diffable_rule_fields/note.ts | 655 ++++++++ .../diffable_rule_fields/references.ts | 655 ++++++++ .../related_integrations.ts | 1020 +++++++++++++ .../diffable_rule_fields/required_fields.ts | 1031 +++++++++++++ .../diffable_rule_fields/risk_score.ts | 655 ++++++++ .../risk_score_mapping.ts | 1110 ++++++++++++++ .../rule_name_override.ts | 655 ++++++++ .../diffable_rule_fields/rule_schedule.ts | 819 ++++++++++ .../diffable_rule_fields/setup.ts | 655 ++++++++ .../diffable_rule_fields/severity.ts | 657 ++++++++ .../diffable_rule_fields/severity_mapping.ts | 1110 ++++++++++++++ .../diffable_rule_fields/tags.ts | 655 ++++++++ .../diffable_rule_fields/threat.ts | 1240 +++++++++++++++ .../diffable_rule_fields/threat_index.ts | 660 ++++++++ .../threat_indicator_path.ts | 660 ++++++++ .../diffable_rule_fields/threat_mapping.ts | 746 +++++++++ .../diffable_rule_fields/threat_query.ts | 811 ++++++++++ .../diffable_rule_fields/threshold.ts | 660 ++++++++ .../diffable_rule_fields/timeline_template.ts | 694 +++++++++ .../timestamp_override.ts | 655 ++++++++ .../trial_license_complete_tier/index.ts | 5 +- .../alert_suppression.ts | 331 ---- .../anomaly_threshold.ts | 336 ----- .../building_block.ts | 324 ---- .../data_source.ts | 647 -------- .../description.ts | 383 ----- .../review_prebuilt_rule_upgrade/eql_query.ts | 421 ------ .../esql_query.ts | 412 ----- .../false_positives.ts | 331 ---- .../history_window_start.ts | 336 ----- .../investigation_fields.ts | 331 ---- .../kql_query.inline_query.ts | 450 ------ .../kql_query.saved_query.ts | 374 ----- .../machine_learning_job_id.ts | 336 ----- .../max_signals.ts | 331 ---- .../review_prebuilt_rule_upgrade/name.ts | 331 ---- .../new_terms_fields.ts | 336 ----- .../review_prebuilt_rule_upgrade/note.ts | 377 ----- .../references.ts | 331 ---- .../related_integrations.ts | 553 ------- .../required_fields.ts | 545 ------- .../risk_score.ts | 331 ---- .../risk_score_mapping.ts | 597 -------- .../rule_name_override.ts | 331 ---- .../rule_schedule.ts | 435 ------ .../review_prebuilt_rule_upgrade/setup.ts | 377 ----- .../review_prebuilt_rule_upgrade/severity.ts | 333 ----- .../severity_mapping.ts | 597 -------- .../review_prebuilt_rule_upgrade/tags.ts | 331 ---- .../review_prebuilt_rule_upgrade/threat.ts | 673 --------- .../threat_index.ts | 336 ----- .../threat_indicator_path.ts | 336 ----- .../threat_mapping.ts | 348 ----- .../threat_query.ts | 432 ------ .../review_prebuilt_rule_upgrade/threshold.ts | 336 ----- .../timeline_template.ts | 350 ----- .../timestamp_override.ts | 331 ---- .../prebuilt_rules/set_up_rule_upgrade.ts | 8 +- 75 files changed, 27477 insertions(+), 14297 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/{review_prebuilt_rule_upgrade => diffable_rule_fields}/index.ts (97%) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts new file mode 100644 index 0000000000000..6a97b85da8f12 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function alertSuppressionField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"alert_suppression"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + alert_suppression: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldC'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldC'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldC'] }, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldA'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + alert_suppression: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldA'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldB'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + base_version: { group_by: ['fieldA'] }, + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldC'] }, + merged_version: { group_by: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + alert_suppression: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + alert_suppression: { + current_version: { group_by: ['fieldB'] }, + target_version: { group_by: ['fieldC'] }, + merged_version: { group_by: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + alert_suppression: { + pick_version: 'RESOLVED', + resolved_value: { group_by: ['fieldD'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + expect(upgradedRule.body).toMatchObject({ + alert_suppression: { group_by: ['fieldD'] }, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts new file mode 100644 index 0000000000000..7bab3cb445c5c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function anomalyThresholdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"anomaly_threshold"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + anomaly_threshold: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 30, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 30, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 30, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 10, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 20, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 20, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 30, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 30, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 30, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 10, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 20, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 20, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 30, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 30, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 30, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 20, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 20, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 20, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 30, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 30, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 30, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + base_version: 10, + current_version: 20, + target_version: 30, + merged_version: 20, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 50, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 50, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + anomaly_threshold: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 30, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 30, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 30, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + anomaly_threshold: { + current_version: 20, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + anomaly_threshold: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + anomaly_threshold: 50, + }); + expect(upgradedRule.body).toMatchObject({ + anomaly_threshold: 50, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts new file mode 100644 index 0000000000000..ed248faf0d21c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts @@ -0,0 +1,648 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function buildingBlockField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"building_block"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + building_block: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: undefined, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).not.toMatchObject({ + building_block_type: expect.anything(), + }); + expect(upgradedRule.body).not.toMatchObject({ + building_block_type: expect.anything(), + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + building_block: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).not.toMatchObject({ + building_block_type: expect.anything(), + }); + expect(upgradedRule.body).not.toMatchObject({ + building_block_type: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: '', + }, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + target_version: { type: 'default' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: '', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: '', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + target_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'custom', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'custom', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + building_block: { + base_version: { type: 'default' }, + current_version: { type: 'custom' }, + merged_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + building_block: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + building_block: { + current_version: { type: 'custom' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + building_block: { + pick_version: 'RESOLVED', + resolved_value: { type: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + building_block_type: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + building_block_type: 'resolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts new file mode 100644 index 0000000000000..8173af1110c5c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts @@ -0,0 +1,1332 @@ +/* + * 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 expect from 'expect'; +import { + DataSourceType, + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function dataSourceField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"data_source" with index patterns', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + merged_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexB', 'indexC'], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + merged_version: { + type: DataSourceType.index_patterns, + index_patterns: ['indexA', 'indexC'], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + index: ['indexResolved'], + }); + expect(upgradedRule.body).toMatchObject({ + index: ['indexResolved'], + }); + }); + }); + }); + }); + + describe('"data_source" with data view', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).not.toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewB', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewB', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewB', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + data_source: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + data_source: { + current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + data_source: { + pick_version: 'RESOLVED', + resolved_value: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + expect(upgradedRule.body).toMatchObject({ + data_view_id: 'dataViewResolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts new file mode 100644 index 0000000000000..507fb514384b2 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts @@ -0,0 +1,663 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function descriptionField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"description"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + description: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: 'Original description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 3', + merged_version: 'Original description line 1\nOriginal description line 3', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + description: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Original description line 1\nOriginal description line 3', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Original description line 1\nOriginal description line 3', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 2', + merged_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }); + expect(upgradedRule.body).toMatchObject({ + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description', + current_version: 'Updated description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Updated description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Updated description', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + description: { + base_version: 'Original description line 1\nOriginal description line 2', + current_version: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + target_version: 'Original description line 1\nOriginal description line 3', + merged_version: + 'Customized description\nOriginal description line 1\nOriginal description line 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + description: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + description: { + current_version: 'Customized description', + target_version: 'Updated description', + merged_version: 'Updated description', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + description: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved description', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + description: 'Resolved description', + }); + expect(upgradedRule.body).toMatchObject({ + description: 'Resolved description', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts new file mode 100644 index 0000000000000..33216e16ac564 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts @@ -0,0 +1,793 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function eqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"eql_query"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + eql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + eql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + eql_query: { + base_version: { + query: 'any where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'host where host.name == "something"', + language: 'eql', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + eql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + eql_query: { + current_version: { + query: 'host where host.name == "something"', + language: 'eql', + filters: [], + }, + target_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + eql_query: { + pick_version: 'RESOLVED', + resolved_value: { + query: 'resolved where true', + language: 'eql', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved where true', + language: 'eql', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts new file mode 100644 index 0000000000000..e328196994c84 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts @@ -0,0 +1,756 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function esqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"esql_query"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + esql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + esql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM indexB METADATA _id', + language: 'esql', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + esql_query: { + base_version: { + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + esql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + esql_query: { + current_version: { + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + target_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + merged_version: { + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + esql_query: { + pick_version: 'RESOLVED', + resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'FROM resolved METADATA _id', + language: 'esql', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts new file mode 100644 index 0000000000000..f9bc9ca1f6cfd --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function falsePositivesField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"false_positives"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + false_positives: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example1'], + target_version: ['example2'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + false_positives: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['example2'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['example2'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example3'], + }, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example3'], + target_version: ['example1'], + merged_version: ['example3'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['example3'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['example3'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example2'], + target_version: ['example2'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['example2'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['example2'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + false_positives: { + base_version: ['example1'], + current_version: ['example2'], + target_version: ['example3'], + merged_version: ['example2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + false_positives: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + false_positives: { + current_version: ['example2'], + target_version: ['example3'], + merged_version: ['example3'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + false_positives: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + false_positives: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + false_positives: ['resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts new file mode 100644 index 0000000000000..3f29eacd9e83a --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function historyWindowStartField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"history_window_start"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + history_window_start: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-30m', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30m', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30m', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-1h', + target_version: 'now-30m', + merged_version: 'now-30m', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + history_window_start: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30m', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30m', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-2h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-2h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-2h', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-1h', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-2h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-2h', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-30h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30h', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-2h', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-2h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-2h', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-30h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30h', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + history_window_start: { + base_version: 'now-1h', + current_version: 'now-2h', + target_version: 'now-30m', + merged_version: 'now-2h', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-30h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30h', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + history_window_start: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-30h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-30h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-30h', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + history_window_start: { + current_version: 'now-2h', + target_version: 'now-30m', + merged_version: 'now-30m', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + history_window_start: { + pick_version: 'RESOLVED', + resolved_value: 'now-5h', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + history_window_start: 'now-5h', + }); + expect(upgradedRule.body).toMatchObject({ + history_window_start: 'now-5h', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/index.ts similarity index 97% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/index.ts index edaa6449a1d4e..7b90b4821856c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/index.ts @@ -50,7 +50,7 @@ export default (context: FtrProviderContext): void => { const supertest = context.getService('supertest'); const log = context.getService('log'); - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + describe('@ess @serverless @skipInServerlessMKI diffable rule fields', () => { beforeEach(async () => { await deleteAllRules(supertest, log); await deleteAllTimelines(es, log); @@ -99,6 +99,8 @@ export default (context: FtrProviderContext): void => { threatQueryField(context); threatMappingField(context); threatIndicatorPathField(context); + + // Threshold rule type thresholdField(context); // Machine Learning rule type diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts new file mode 100644 index 0000000000000..748b8802742b8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function investigationFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"investigation_fields"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + investigation_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldA'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + investigation_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldA'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldB'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + base_version: { field_names: ['fieldA'] }, + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldC'] }, + merged_version: { field_names: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + investigation_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + investigation_fields: { + current_version: { field_names: ['fieldB'] }, + target_version: { field_names: ['fieldC'] }, + merged_version: { field_names: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + investigation_fields: { + pick_version: 'RESOLVED', + resolved_value: { field_names: ['resolved'] }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + investigation_fields: { field_names: ['resolved'] }, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts new file mode 100644 index 0000000000000..d90f8380a0485 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts @@ -0,0 +1,837 @@ +/* + * 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 expect from 'expect'; +import { + KqlQueryType, + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +const RULE_TYPES = ['query', 'threat_match', /* 'threshold',*/ 'new_terms'] as const; + +export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + for (const ruleType of RULE_TYPES) { + describe('"kql_query" with inline query', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + type: ruleType, + query: '*:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + type: ruleType, + query: '*:*', + language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: '*:*', + language: 'kuery', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + type: ruleType, + query: '*:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + type: ruleType, + query: '*:*', + language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: 'process.name:*.sys', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: { + type: ruleType, + query: '*:*', + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + current_version: { + query: '*:*', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + target_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged_version: { + query: 'process.name:*.sys', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + query: 'resolved:*', + language: 'kuery', + }); + }); + }); + }); + }); + } +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts new file mode 100644 index 0000000000000..7b22a5d93849b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts @@ -0,0 +1,720 @@ +/* + * 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 expect from 'expect'; +import { + KqlQueryType, + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"kql_query" with saved query', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id1', + }, + target_version: { + saved_query_id: 'saved_query_id2', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'saved_query_id2', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'saved_query_id2', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id1', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'saved_query_id2', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'saved_query_id2', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id2', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'saved_query_id2', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'saved_query_id2', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + base_version: { + saved_query_id: 'saved_query_id1', + }, + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id3', + }, + merged_version: { + saved_query_id: 'saved_query_id2', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + kql_query: { + current_version: { + saved_query_id: 'saved_query_id2', + }, + target_version: { + saved_query_id: 'saved_query_id3', + }, + merged_version: { + saved_query_id: 'saved_query_id3', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + saved_id: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + saved_id: 'resolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts new file mode 100644 index 0000000000000..9ac6eb48bd6a9 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function machineLearningJobIdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"machine_learning_job_id"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + machine_learning_job_id: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobA'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobA'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobB'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['jobB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + base_version: ['jobA'], + current_version: ['jobB'], + target_version: ['jobC'], + merged_version: ['jobB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + machine_learning_job_id: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + machine_learning_job_id: { + current_version: ['jobB'], + target_version: ['jobC'], + merged_version: ['jobC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + machine_learning_job_id: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + machine_learning_job_id: ['resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts new file mode 100644 index 0000000000000..5d70b4a895d70 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function maxSignalsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"max_signals"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 100, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + max_signals: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 100, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + max_signals: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 150, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 150, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 100, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 100, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 130, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 130, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 130, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 130, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 130, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 130, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + max_signals: { + base_version: 100, + current_version: 130, + target_version: 150, + merged_version: 130, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 130, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + max_signals: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + max_signals: { + current_version: 130, + target_version: 150, + merged_version: 150, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + max_signals: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + max_signals: 50, + }); + expect(upgradedRule.body).toMatchObject({ + max_signals: 50, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts new file mode 100644 index 0000000000000..3771ccc9276c8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function nameField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"name"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Original name', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + name: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Original name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + name: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Updated name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Updated name', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Original name', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Original name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Customized name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Customized name', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Updated name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Updated name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Updated name', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + name: { + base_version: 'Original name', + current_version: 'Customized name', + target_version: 'Updated name', + merged_version: 'Customized name', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + name: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + name: { + current_version: 'Customized name', + target_version: 'Updated name', + merged_version: 'Updated name', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + name: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved name', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + name: 'Resolved name', + }); + expect(upgradedRule.body).toMatchObject({ + name: 'Resolved name', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts new file mode 100644 index 0000000000000..ade40eac6d0f8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function newTermsFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"new_terms_fields"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + new_terms_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldA'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldB'], + merged_version: ['fieldB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['fieldB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + base_version: ['fieldA'], + current_version: ['fieldB'], + target_version: ['fieldA', 'fieldC'], + merged_version: ['fieldB', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + new_terms_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + new_terms_fields: { + current_version: ['fieldB'], + target_version: ['fieldA', 'fieldC'], + merged_version: ['fieldA', 'fieldC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + new_terms_fields: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + new_terms_fields: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + new_terms_fields: ['resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts new file mode 100644 index 0000000000000..59955707c0327 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function noteField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"note"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'some note', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + note: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'some note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + note: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'updated note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'updated note', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'some note', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'customized note', + target_version: 'some note', + merged_version: 'customized note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'customized note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'customized note', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'some note', + current_version: 'updated note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'updated note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'updated note', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'line 1\nline 2', + }, + patch: { + note: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + note: 'line 1\nline 3', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + note: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + note: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + note: { + current_version: 'customized note', + target_version: 'updated note', + merged_version: 'updated note', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + note: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved note', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + note: 'Resolved note', + }); + expect(upgradedRule.body).toMatchObject({ + note: 'Resolved note', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts new file mode 100644 index 0000000000000..bfd2c9fb11376 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function referencesField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"references"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + references: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + references: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['http://url-1', 'http://url-2'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['http://url-1', 'http://url-2'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-2'], + target_version: ['http://url-1'], + merged_version: ['http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['http://url-2'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['http://url-2'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-1', 'http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-1', 'http://url-2'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['http://url-1', 'http://url-2'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['http://url-1', 'http://url-2'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-3'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + references: { + base_version: ['http://url-1'], + current_version: ['http://url-2'], + target_version: ['http://url-1', 'http://url-3'], + merged_version: ['http://url-2', 'http://url-3'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + references: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-3'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + references: { + current_version: ['http://url-3'], + target_version: ['http://url-1', 'http://url-2'], + merged_version: ['http://url-1', 'http://url-2'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + references: { + pick_version: 'RESOLVED', + resolved_value: ['https://resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + references: ['https://resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + references: ['https://resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts new file mode 100644 index 0000000000000..f381fc9776a52 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts @@ -0,0 +1,1020 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function relatedIntegrationsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"related_integrations"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + related_integrations: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + related_integrations: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^2.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^2.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^2.0.0', + }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + related_integrations: { + base_version: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + related_integrations: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', + }, + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + related_integrations: { + current_version: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + target_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + merged_version: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + related_integrations: { + pick_version: 'RESOLVED', + resolved_value: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts new file mode 100644 index 0000000000000..529caa48f55d8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts @@ -0,0 +1,1031 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function requiredFieldsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"required_fields"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + required_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + required_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + required_fields: { + base_version: [ + { + name: 'fieldA', + type: 'string', + ecs: false, + }, + ], + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + required_fields: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', + }, + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + required_fields: { + current_version: [ + { + name: 'fieldB', + type: 'string', + ecs: false, + }, + ], + target_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + merged_version: [ + { + name: 'fieldC', + type: 'string', + ecs: false, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + required_fields: { + pick_version: 'RESOLVED', + resolved_value: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts new file mode 100644 index 0000000000000..bc548f193b0f6 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function riskScoreField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"risk_score"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 10, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + risk_score: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 50, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 50, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 10, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 30, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 30, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 50, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 50, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 50, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 10, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 10, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 50, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 50, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 70, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 70, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 70, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 50, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 50, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 50, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 50, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 70, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 70, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 70, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score: { + base_version: 10, + current_version: 50, + target_version: 30, + merged_version: 50, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 70, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 70, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 70, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 30, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + risk_score: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 70, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 70, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 70, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score: { + current_version: 50, + target_version: 30, + merged_version: 30, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score: { + pick_version: 'RESOLVED', + resolved_value: 70, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score: 70, + }); + expect(upgradedRule.body).toMatchObject({ + risk_score: 70, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts new file mode 100644 index 0000000000000..df91732b729f6 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts @@ -0,0 +1,1110 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function riskScoreMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"risk_score_mapping"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + risk_score_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + risk_score_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, + }, + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + risk_score_mapping: { + current_version: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + merged_version: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + risk_score_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts new file mode 100644 index 0000000000000..218745b2fbfa2 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function ruleNameOverrideField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"rule_name_override"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + rule_name_override: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldA' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_name_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldA' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldB' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + base_version: { field_name: 'fieldA' }, + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldC' }, + merged_version: { field_name: 'fieldB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + rule_name_override: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_name_override: { + current_version: { field_name: 'fieldB' }, + target_version: { field_name: 'fieldC' }, + merged_version: { field_name: 'fieldC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_name_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + rule_name_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + rule_name_override: 'resolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts new file mode 100644 index 0000000000000..f6134f94a5a07 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts @@ -0,0 +1,819 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function ruleScheduleField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"rule_schedule"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + rule_schedule: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_schedule: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '5m', + from: 'now-15m', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '5m', + from: 'now-15m', + to: 'now', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '5m', + from: 'now-20m', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '5m', + from: 'now-20m', + to: 'now', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', + to: 'now', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '5m', + from: 'now-20m', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '5m', + from: 'now-20m', + to: 'now', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + base_version: { + interval: '5m', + from: 'now-10m', + to: 'now', + }, + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', + to: 'now', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + rule_schedule: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + rule_schedule: { + current_version: { + interval: '5m', + from: 'now-20m', + to: 'now', + }, + target_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + merged_version: { + interval: '5m', + from: 'now-15m', + to: 'now', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + rule_schedule: { + pick_version: 'RESOLVED', + resolved_value: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + expect(upgradedRule.body).toMatchObject({ + interval: '1h', + from: 'now-2h', + to: 'now', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts new file mode 100644 index 0000000000000..7f25be9388b0c --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function setupField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"setup"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + setup: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'some setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + setup: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'updated setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'updated setup', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'customized setup', + target_version: 'some setup', + merged_version: 'customized setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'customized setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'customized setup', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'some setup', + current_version: 'updated setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'updated setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'updated setup', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'line 1\nline 2', + }, + patch: { + setup: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + setup: 'line 1\nline 3', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + setup: { + base_version: 'line 1\nline 2', + current_version: 'Customized line\nline 1\nline 2', + target_version: 'line 1\nline 3', + merged_version: 'Customized line\nline 1\nline 3', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + setup: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + setup: { + current_version: 'customized setup', + target_version: 'updated setup', + merged_version: 'updated setup', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + setup: { + pick_version: 'RESOLVED', + resolved_value: 'Resolved setup', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + setup: 'Resolved setup', + }); + expect(upgradedRule.body).toMatchObject({ + setup: 'Resolved setup', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts new file mode 100644 index 0000000000000..faad4db39adc9 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts @@ -0,0 +1,657 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function severityField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"severity"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: {}, + upgrade: { + type: 'query', + severity: 'low', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + severity: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'high', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'high', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'high', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'low', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'low', + target_version: 'high', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'high', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'high', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'medium', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'medium', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'medium', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'low', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'low', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'medium', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'medium', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'critical', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'critical', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'critical', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'medium', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'medium', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'medium', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'medium', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'critical', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'critical', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'critical', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity: { + base_version: 'low', + current_version: 'medium', + target_version: 'high', + merged_version: 'medium', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'critical', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'critical', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'critical', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'medium', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + severity: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'critical', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'critical', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'critical', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity: { + current_version: 'medium', + target_version: 'high', + merged_version: 'high', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity: { + pick_version: 'RESOLVED', + resolved_value: 'critical', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity: 'critical', + }); + expect(upgradedRule.body).toMatchObject({ + severity: 'critical', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts new file mode 100644 index 0000000000000..0b9c8783c18a8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts @@ -0,0 +1,1110 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function severityMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"severity_mapping"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + severity_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + base_version: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + merged_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + severity_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', + }, + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + severity_mapping: { + current_version: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + target_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + merged_version: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + severity_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts new file mode 100644 index 0000000000000..9d4abd6e227dd --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function tagsField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"tags"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + tags: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagA'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + tags: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['tagB'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['tagB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagA'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['tagB'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['tagB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagB'], + merged_version: ['tagB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['tagB'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['tagB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + tags: { + base_version: ['tagA'], + current_version: ['tagB'], + target_version: ['tagC'], + merged_version: ['tagB', 'tagC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + tags: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + tags: { + current_version: ['tagB'], + target_version: ['tagC'], + merged_version: ['tagC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + tags: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + tags: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + tags: ['resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts new file mode 100644 index 0000000000000..c6c0a92fc7d02 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts @@ -0,0 +1,1240 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threat"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat: { + base_version: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, + }, + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat: { + current_version: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + target_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + merged_version: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, + }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat: { + pick_version: 'RESOLVED', + resolved_value: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts new file mode 100644 index 0000000000000..6bf8e6272914b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatIndexField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threat_index"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_index: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexA'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_index: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexA'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexB'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexB'], + target_version: ['indexB'], + merged_version: ['indexB'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['indexB'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['indexB'], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_index: { + base_version: ['indexA'], + current_version: ['indexD'], + target_version: ['indexB', 'indexC'], + merged_version: ['indexD', 'indexB', 'indexC'], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexD'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_index: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_index: { + current_version: ['indexD'], + target_version: ['indexB', 'indexC'], + merged_version: ['indexB', 'indexC'], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_index: { + pick_version: 'RESOLVED', + resolved_value: ['resolved'], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_index: ['resolved'], + }); + expect(upgradedRule.body).toMatchObject({ + threat_index: ['resolved'], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts new file mode 100644 index 0000000000000..20e073ddcd716 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatIndicatorPathField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threat_indicator_path"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_indicator_path: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldA', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldA', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldB', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + base_version: 'fieldA', + current_version: 'fieldB', + target_version: 'fieldC', + merged_version: 'fieldB', + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_indicator_path: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_indicator_path: { + current_version: 'fieldB', + target_version: 'fieldC', + merged_version: 'fieldC', + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_indicator_path: { + pick_version: 'RESOLVED', + resolved_value: 'resolved', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_indicator_path: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + threat_indicator_path: 'resolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts new file mode 100644 index 0000000000000..1d9cff8197a37 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts @@ -0,0 +1,746 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatMappingField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threat_mapping"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, + ], + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_mapping: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, + ], + }, + patch: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, + ], + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_mapping: { + current_version: [ + { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, + ], + target_version: [ + { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, + ], + merged_version: [ + { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, + ], + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_mapping: { + pick_version: 'RESOLVED', + resolved_value: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + expect(upgradedRule.body).toMatchObject({ + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts new file mode 100644 index 0000000000000..22a43facbdce6 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts @@ -0,0 +1,811 @@ +/* + * 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 expect from 'expect'; +import { + KqlQueryType, + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function threatQueryField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threat_query"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + language: 'kuery', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_query: { + base_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.exe', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threat_query: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threat_query: { + current_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.sys', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'process.name:*.com', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threat_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + threat_query: 'resolved:*', + threat_language: 'kuery', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts new file mode 100644 index 0000000000000..fe55b767cdb53 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts @@ -0,0 +1,660 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function thresholdField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"threshold"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threshold: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldA'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldA'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldB'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 10, field: ['fieldB'] }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threshold: { + base_version: { value: 10, field: ['fieldA'] }, + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldC'] }, + merged_version: { value: 10, field: ['fieldB'] }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + threshold: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + threshold: { + current_version: { value: 10, field: ['fieldB'] }, + target_version: { value: 10, field: ['fieldC'] }, + merged_version: { value: 10, field: ['fieldC'] }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + threshold: { + pick_version: 'RESOLVED', + resolved_value: { value: 50, field: 'resolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + expect(upgradedRule.body).toMatchObject({ + threshold: { value: 50, field: ['resolved'] }, + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts new file mode 100644 index 0000000000000..e03781d584681 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts @@ -0,0 +1,694 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function timelineTemplateField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"timeline_template"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + timeline_template: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timeline_template: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'B', + timeline_title: 'timelineB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timeline_template: { + base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + timeline_template: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timeline_template: { + current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, + target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged_version: { timeline_id: 'C', timeline_title: 'timelineC' }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timeline_template: { + pick_version: 'RESOLVED', + resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + expect(upgradedRule.body).toMatchObject({ + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts new file mode 100644 index 0000000000000..d68f20c96f882 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts @@ -0,0 +1,655 @@ +/* + * 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 expect from 'expect'; +import { + ModeEnum, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export function timestampOverrideField({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + }; + + describe('"timestamp_override"', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + timestamp_override: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldA', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timestamp_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldA', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldB', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }, + }); + }); + + it('upgrades to MERGED version', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'fieldB', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'fieldB', + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + base_version: { field_name: 'fieldA', fallback_disabled: false }, + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldC', fallback_disabled: false }, + merged_version: { field_name: 'fieldB', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + timestamp_override: expect.anything(), + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }, + removeInstalledAssets: true, + deps, + }); + }); + + it('returns upgrade preview', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules).toHaveLength(1); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 1, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 2, + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).toMatchObject({ + timestamp_override: { + current_version: { field_name: 'fieldB', fallback_disabled: false }, + target_version: { field_name: 'fieldC', fallback_disabled: false }, + merged_version: { field_name: 'fieldC', fallback_disabled: false }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }, + }); + }); + + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + fields: { + timestamp_override: { + pick_version: 'RESOLVED', + resolved_value: { field_name: 'resolved', fallback_disabled: false }, + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated[0]).toMatchObject({ + timestamp_override: 'resolved', + }); + expect(upgradedRule.body).toMatchObject({ + timestamp_override: 'resolved', + }); + }); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 3087e45c1a97b..77f2dba569460 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -15,10 +15,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./upgrade_prebuilt_rules')); - loadTestFile(require.resolve('./upgrade_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); - loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.all_rules_mode')); - loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.specific_rules_mode')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.single_line_string_fields')); @@ -50,5 +47,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); loadTestFile(require.resolve('./review_prebuilt_rule_upgrade')); + loadTestFile(require.resolve('./diffable_rule_fields')); + loadTestFile(require.resolve('./upgrade_prebuilt_rules')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts deleted file mode 100644 index 90e67b02d456c..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/alert_suppression.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function alertSuppressionField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "alert_suppression" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - alert_suppression: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldA'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldA'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldC'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldC'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - alert_suppression: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldC'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldC'] }, - merged_version: { group_by: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts deleted file mode 100644 index ed684a5c2da2f..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/anomaly_threshold.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function anomalyThresholdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "anomaly_threshold" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: {}, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - anomaly_threshold: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: {}, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 10, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 10, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 30, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 30, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - anomaly_threshold: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - current_version: 20, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts deleted file mode 100644 index e6ba3c06f4fba..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/building_block.ts +++ /dev/null @@ -1,324 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function buildingBlockField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "building_block" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: {}, - upgrade: { - type: 'query', - building_block_type: 'default', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - building_block: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: {}, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: '', - }, - upgrade: { - type: 'query', - building_block_type: 'default', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - target_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: 'custom', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - target_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: 'custom', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - building_block: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - building_block: { - current_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts deleted file mode 100644 index 807795215b8eb..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/data_source.ts +++ /dev/null @@ -1,647 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - DataSourceType, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function dataSourceField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "data_source" field with index patterns', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'query', - index: ['indexA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA', 'indexC'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexA', 'indexC'], - }, - merged_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexB', 'indexC'], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA', 'indexC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexA', 'indexC'], - }, - merged_version: { - type: DataSourceType.index_patterns, - index_patterns: ['indexA', 'indexC'], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); - - describe('preview rule upgrade for "data_source" field with data view', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: {}, - upgrade: { - type: 'query', - data_view_id: 'dataViewA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: {}, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - data_source: { - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts deleted file mode 100644 index 00f940f133010..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/description.ts +++ /dev/null @@ -1,383 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function descriptionField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "description" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: {}, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - description: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: {}, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 3', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: 'Original description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 3', - merged_version: 'Original description line 1\nOriginal description line 3', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: { - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 2', - merged_version: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Updated description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description', - current_version: 'Updated description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: { - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 3', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 3', - merged_version: - 'Customized description\nOriginal description line 1\nOriginal description line 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Customized description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description', - current_version: 'Customized description', - target_version: 'Updated description', - merged_version: 'Customized description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Updated description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - description: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Customized description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - description: { - current_version: 'Customized description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts deleted file mode 100644 index e23ad4f49419c..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/eql_query.ts +++ /dev/null @@ -1,421 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function eqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "eql_query" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: {}, - upgrade: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - eql_query: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: {}, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { - query: 'any where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'host where host.name == "something"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'host where host.name == "something"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'host where host.name == "something"', - language: 'eql', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - eql_query: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - eql_query: { - current_version: { - query: 'host where host.name == "something"', - language: 'eql', - filters: [], - }, - target_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts deleted file mode 100644 index 6b056a9d02432..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/esql_query.ts +++ /dev/null @@ -1,412 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function esqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "esql_query" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: {}, - upgrade: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - esql_query: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: {}, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - esql_query: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - esql_query: { - current_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - target_version: { - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts deleted file mode 100644 index db82e03b12e61..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/false_positives.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function falsePositivesField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "false_positives" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: {}, - upgrade: { - type: 'query', - false_positives: ['example1'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - false_positives: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: {}, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example1'], - target_version: ['example2'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example3'], - }, - upgrade: { - type: 'query', - false_positives: ['example1'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example3'], - target_version: ['example1'], - merged_version: ['example3'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example2'], - target_version: ['example2'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example3'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example2'], - target_version: ['example3'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - false_positives: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example3'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - false_positives: { - current_version: ['example2'], - target_version: ['example3'], - merged_version: ['example3'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts deleted file mode 100644 index 58bca149f56c1..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/history_window_start.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function historyWindowStartField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "history_window_start" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: {}, - upgrade: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - history_window_start: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: {}, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-1h', - target_version: 'now-30m', - merged_version: 'now-30m', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-1h', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-2h', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-30m', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - history_window_start: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - history_window_start: { - current_version: 'now-2h', - target_version: 'now-30m', - merged_version: 'now-30m', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts deleted file mode 100644 index 90a360ebaf887..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/investigation_fields.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function investigationFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "investigation_fields" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - investigation_fields: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldA'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldA'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldC'] }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldC'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - investigation_fields: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldC'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldC'] }, - merged_version: { field_names: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts deleted file mode 100644 index fdaf637c4f959..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.inline_query.ts +++ /dev/null @@ -1,450 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - KqlQueryType, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -const RULE_TYPES = ['query', 'threat_match', /* 'threshold',*/ 'new_terms'] as const; - -export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - for (const ruleType of RULE_TYPES) { - describe(`preview rule upgrade for "kql_query" field with inline query for "${ruleType}" rule type`, () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - type: ruleType, - query: '*:*', - }, - upgrade: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - type: ruleType, - query: '*:*', - }, - upgrade: { - type: ruleType, - query: '*:*', - language: 'kuery', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - type: ruleType, - query: '*:*', - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - type: ruleType, - query: 'process.name:*.sys', - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: { - type: ruleType, - query: '*:*', - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - current_version: { - query: '*:*', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - merged_version: { - query: 'process.name:*.sys', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); - } -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts deleted file mode 100644 index ab8b74d13ae29..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/kql_query.saved_query.ts +++ /dev/null @@ -1,374 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "kql_query" field with saved query', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: {}, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: {}, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id1', - }, - target_version: { - saved_query_id: 'saved_query_id2', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id1', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id2', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id3', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id3', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id3', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - kql_query: { - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id3', - }, - merged_version: { - saved_query_id: 'saved_query_id3', - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts deleted file mode 100644 index 303f06bb86271..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/machine_learning_job_id.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function machineLearningJobIdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "machine_learning_job_id" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: {}, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - machine_learning_job_id: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: {}, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobA'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobA'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobC'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - machine_learning_job_id: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - current_version: ['jobB'], - target_version: ['jobC'], - merged_version: ['jobC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts deleted file mode 100644 index 0f4cf298cdd97..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/max_signals.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function maxSignalsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "max_signals" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: {}, - upgrade: { - type: 'query', - max_signals: 100, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - max_signals: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: {}, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 100, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 100, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 100, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 130, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 130, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 150, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 130, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - max_signals: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - max_signals: { - current_version: 130, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts deleted file mode 100644 index 4d0c9cac008fb..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/name.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function nameField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "name" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: {}, - upgrade: { - type: 'query', - name: 'Original name', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - name: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: {}, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Original name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Original name', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Original name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Updated name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Updated name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Updated name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Updated name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - name: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - name: { - current_version: 'Customized name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts deleted file mode 100644 index 805ecef23dd60..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/new_terms_fields.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function newTermsFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "new_terms_fields" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: {}, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - new_terms_fields: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: {}, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldA'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA', 'fieldC'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA', 'fieldC'], - merged_version: ['fieldB', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - new_terms_fields: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA', 'fieldC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - current_version: ['fieldB'], - target_version: ['fieldA', 'fieldC'], - merged_version: ['fieldA', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts deleted file mode 100644 index cde493b0b0040..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/note.ts +++ /dev/null @@ -1,377 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function noteField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "note" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: {}, - upgrade: { - type: 'query', - note: 'some note', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - note: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: {}, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'some note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'some note', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'customized note', - target_version: 'some note', - merged_version: 'customized note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'updated note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'line 1\nline 2', - }, - patch: { - note: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - note: 'line 1\nline 3', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'customized note', - target_version: 'updated note', - merged_version: 'customized note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - note: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - note: { - current_version: 'customized note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts deleted file mode 100644 index be9859c82d7d1..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/references.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function referencesField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "references" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: {}, - upgrade: { - type: 'query', - references: ['http://url-1'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - references: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: {}, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-2'], - target_version: ['http://url-1'], - merged_version: ['http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-1', 'http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1', 'http://url-2'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-3'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-2'], - target_version: ['http://url-1', 'http://url-3'], - merged_version: ['http://url-2', 'http://url-3'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - references: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-3'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - references: { - current_version: ['http://url-3'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts deleted file mode 100644 index fc2b7cd8377e7..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/related_integrations.ts +++ /dev/null @@ -1,553 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function relatedIntegrationsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "related_integrations" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - related_integrations: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - merged_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - merged_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - merged_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - current_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - merged_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - related_integrations: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - related_integrations: { - current_version: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - target_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - merged_version: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts deleted file mode 100644 index 383563f507b92..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/required_fields.ts +++ /dev/null @@ -1,545 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function requiredFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "required_fields" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - required_fields: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldC', - type: 'string', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ - { - name: 'fieldA', - type: 'string', - ecs: false, - }, - ], - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldC', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - required_fields: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldC', - type: 'string', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - required_fields: { - current_version: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - target_version: [ - { - name: 'fieldC', - type: 'string', - ecs: false, - }, - ], - merged_version: [ - { - name: 'fieldC', - type: 'string', - ecs: false, - }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts deleted file mode 100644 index a696eaaf535ff..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function riskScoreField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "risk_score" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: {}, - upgrade: { - type: 'query', - risk_score: 10, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - risk_score: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: {}, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 10, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 10, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 10, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 50, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 50, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 30, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 30, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - risk_score: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score: { - current_version: 50, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts deleted file mode 100644 index 9ed727a136f01..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/risk_score_mapping.ts +++ /dev/null @@ -1,597 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function riskScoreMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "risk_score_mapping" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - risk_score_mapping: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - risk_score_mapping: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - current_version: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - merged_version: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts deleted file mode 100644 index d711326df4587..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_name_override.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function ruleNameOverrideField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "rule_name_override" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - rule_name_override: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - rule_name_override: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldA' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldA' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldC' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - rule_name_override: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldC' }, - merged_version: { field_name: 'fieldC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts deleted file mode 100644 index f4aa2349a23d4..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/rule_schedule.ts +++ /dev/null @@ -1,435 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function ruleScheduleField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "rule_schedule" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: {}, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - rule_schedule: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: {}, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - target_version: { - interval: '5m', - from: 'now-15m', - to: 'now', - }, - merged_version: { - interval: '5m', - from: 'now-15m', - to: 'now', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - target_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - merged_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-20m', - to: 'now', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - target_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - merged_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - target_version: { - interval: '5m', - from: 'now-15m', - to: 'now', - }, - merged_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-20m', - to: 'now', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - rule_schedule: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - current_version: { - interval: '5m', - from: 'now-20m', - to: 'now', - }, - target_version: { - interval: '5m', - from: 'now-15m', - to: 'now', - }, - merged_version: { - interval: '5m', - from: 'now-15m', - to: 'now', - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts deleted file mode 100644 index 0b348f2bc4814..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/setup.ts +++ /dev/null @@ -1,377 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function setupField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "setup" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: {}, - upgrade: { - type: 'query', - setup: 'some setup', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - setup: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: {}, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'some setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'some setup', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'customized setup', - target_version: 'some setup', - merged_version: 'customized setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'updated setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'line 1\nline 2', - }, - patch: { - setup: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - setup: 'line 1\nline 3', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'customized setup', - target_version: 'updated setup', - merged_version: 'customized setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - setup: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - setup: { - current_version: 'customized setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts deleted file mode 100644 index c5c6283696723..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity.ts +++ /dev/null @@ -1,333 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function severityField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "severity" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: {}, - upgrade: { - type: 'query', - severity: 'low', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - severity: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'low', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'low', - target_version: 'high', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'low', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'low', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'medium', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'medium', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'high', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'medium', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - severity: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity: { - current_version: 'medium', - target_version: 'high', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts deleted file mode 100644 index cfd8dafb7767f..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/severity_mapping.ts +++ /dev/null @@ -1,597 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function severityMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "severity_mapping" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - severity_mapping: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'high', - value: '20', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'high', - value: '20', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'high', - value: '20', - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - merged_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - severity_mapping: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - current_version: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - target_version: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - merged_version: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts deleted file mode 100644 index 81d8948333dd1..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/tags.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function tagsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "tags" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - tags: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagA'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagA'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagC'], - merged_version: ['tagB', 'tagC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - tags: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - tags: { - current_version: ['tagB'], - target_version: ['tagC'], - merged_version: ['tagC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts deleted file mode 100644 index 84a8531633c8f..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat.ts +++ /dev/null @@ -1,673 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function threatField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threat" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat: { - current_version: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - target_version: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - merged_version: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts deleted file mode 100644 index 3bfea17373635..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_index.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function threatIndexField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threat_index" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_index: ['indexA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_index: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexA'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexA'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexA'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB', 'indexC'], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexD'], - target_version: ['indexB', 'indexC'], - merged_version: ['indexD', 'indexB', 'indexC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexD'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_index: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB', 'indexC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_index: { - current_version: ['indexD'], - target_version: ['indexB', 'indexC'], - merged_version: ['indexB', 'indexC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts deleted file mode 100644 index b727d472f722a..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_indicator_path.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function threatIndicatorPathField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threat_indicator_path" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_indicator_path: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldA', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldA', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldC', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_indicator_path: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - current_version: 'fieldB', - target_version: 'fieldC', - merged_version: 'fieldC', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts deleted file mode 100644 index 952a06a54c3fc..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_mapping.ts +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function threatMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threat_mapping" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_mapping: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - }, - patch: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_mapping: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts deleted file mode 100644 index 8ff15200ab8ce..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threat_query.ts +++ /dev/null @@ -1,432 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - KqlQueryType, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function threatQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threat_query" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_query: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.com', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.exe', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.com', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threat_query: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.com', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threat_query: { - current_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.sys', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.com', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'process.name:*.com', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts deleted file mode 100644 index 8dc9ba752167e..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/threshold.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function thresholdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "threshold" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: {}, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threshold: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: {}, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldA'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldA'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldC' }, - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldC'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - threshold: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldC' }, - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - threshold: { - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldC'] }, - merged_version: { value: 10, field: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts deleted file mode 100644 index 0fd82df3e8f09..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timeline_template.ts +++ /dev/null @@ -1,350 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function timelineTemplateField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "timeline_template" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: {}, - upgrade: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - timeline_template: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: {}, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'C', - timeline_title: 'timelineC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - timeline_template: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'C', - timeline_title: 'timelineC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timeline_template: { - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - merged_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts deleted file mode 100644 index 94f285cbf3485..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/review_prebuilt_rule_upgrade/timestamp_override.ts +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function timestampOverrideField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - const deps = { - es, - supertest, - log, - }; - - describe('preview rule upgrade for "timestamp_override" field', () => { - it('does NOT return non-customized field without an upgrade (AAA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - timestamp_override: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - timestamp_override: expect.anything(), - }); - }); - - it('returns non-customized field with an upgrade (AAB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldA', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('returns customized field without an upgrade (ABA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldA', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldA', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with a matching upgrade (ABB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('returns customized field with an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldC', - }, - }, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldC', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - describe('without historical versions', () => { - it('does NOT return a customized field with the matching upgrade (-AA diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).not.toMatchObject({ - timestamp_override: expect.anything(), - }); - }); - - it('returns customized field with an matching upgrade (-AB diff case)', async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.rules).toHaveLength(1); - expect(reviewResponse.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(reviewResponse.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldC', fallback_disabled: false }, - merged_version: { field_name: 'fieldC', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts index 6233b0e057df2..966c34352fdc0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -38,6 +38,8 @@ interface SetUpRuleUpgradeParams { deps: SetUpRuleUpgradeDeps; } +export const DEFAULT_TEST_RULE_ID = 'test-rule'; + export async function setUpRuleUpgrade({ assets, removeInstalledAssets, @@ -48,7 +50,7 @@ export async function setUpRuleUpgrade({ for (const ruleAssets of rulesAssets) { await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(ruleAssets.installed.type, { - rule_id: 'rule-1', + rule_id: DEFAULT_TEST_RULE_ID, version: 1, ...ruleAssets.installed, }), @@ -60,7 +62,7 @@ export async function setUpRuleUpgrade({ for (const ruleAssets of rulesAssets) { if (Object.keys(ruleAssets.patch).length > 0) { await patchRule(deps.supertest, deps.log, { - rule_id: 'rule-1', + rule_id: DEFAULT_TEST_RULE_ID, ...ruleAssets.patch, }); } @@ -73,7 +75,7 @@ export async function setUpRuleUpgrade({ for (const ruleAssets of rulesAssets) { await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(ruleAssets.upgrade.type, { - rule_id: 'rule-1', + rule_id: DEFAULT_TEST_RULE_ID, version: 2, ...ruleAssets.upgrade, }), From 257812c96a60667be249debb35edfb74521b3977 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sat, 1 Feb 2025 13:54:25 +0100 Subject: [PATCH 06/20] move prebuilt rules tests to a proper folder --- .../trial_license_complete_tier/index.ts | 24 ------------------- .../diffable_rule_fields/alert_suppression.ts | 6 ++--- .../diffable_rule_fields/anomaly_threshold.ts | 6 ++--- .../diffable_rule_fields/building_block.ts | 6 ++--- .../diffable_rule_fields/data_source.ts | 12 +++++----- .../diffable_rule_fields/description.ts | 6 ++--- .../diffable_rule_fields/eql_query.ts | 6 ++--- .../diffable_rule_fields/esql_query.ts | 6 ++--- .../diffable_rule_fields/false_positives.ts | 6 ++--- .../history_window_start.ts | 6 ++--- .../diffable_rule_fields/index.ts | 0 .../investigation_fields.ts | 6 ++--- .../kql_query.inline_query.ts | 6 ++--- .../kql_query.saved_query.ts | 6 ++--- .../machine_learning_job_id.ts | 6 ++--- .../diffable_rule_fields/max_signals.ts | 6 ++--- .../diffable_rule_fields/name.ts | 6 ++--- .../diffable_rule_fields/new_terms_fields.ts | 6 ++--- .../diffable_rule_fields/note.ts | 6 ++--- .../diffable_rule_fields/references.ts | 6 ++--- .../related_integrations.ts | 6 ++--- .../diffable_rule_fields/required_fields.ts | 6 ++--- .../diffable_rule_fields/risk_score.ts | 6 ++--- .../risk_score_mapping.ts | 6 ++--- .../rule_name_override.ts | 6 ++--- .../diffable_rule_fields/rule_schedule.ts | 6 ++--- .../diffable_rule_fields/setup.ts | 6 ++--- .../diffable_rule_fields/severity.ts | 6 ++--- .../diffable_rule_fields/severity_mapping.ts | 6 ++--- .../diffable_rule_fields/tags.ts | 6 ++--- .../diffable_rule_fields/threat.ts | 6 ++--- .../diffable_rule_fields/threat_index.ts | 6 ++--- .../threat_indicator_path.ts | 6 ++--- .../diffable_rule_fields/threat_mapping.ts | 6 ++--- .../diffable_rule_fields/threat_query.ts | 6 ++--- .../diffable_rule_fields/threshold.ts | 6 ++--- .../diffable_rule_fields/timeline_template.ts | 6 ++--- .../timestamp_override.ts | 6 ++--- .../customization_enabled/index.ts | 4 ++-- .../bulk_upgrade_all_prebuilt_rules.ts | 0 .../bulk_upgrade_selected_prebuilt_rules.ts | 0 .../upgrade_prebuilt_rules/index.ts | 0 .../upgrade_one_prebuilt_rule.ts | 0 43 files changed, 113 insertions(+), 137 deletions(-) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/alert_suppression.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/anomaly_threshold.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/building_block.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/data_source.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/description.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/eql_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/esql_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/false_positives.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/history_window_start.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/index.ts (100%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/investigation_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/kql_query.inline_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/kql_query.saved_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/machine_learning_job_id.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/max_signals.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/name.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/new_terms_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/note.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/references.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/related_integrations.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/required_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/risk_score.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/risk_score_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/rule_name_override.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/rule_schedule.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/setup.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/severity.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/severity_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/tags.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threat.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threat_index.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threat_indicator_path.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threat_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threat_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/threshold.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/timeline_template.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/diffable_rule_fields/timestamp_override.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts (100%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts (100%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/upgrade_prebuilt_rules/index.ts (100%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/{management/trial_license_complete_tier => prebuilt_rule_customization/customization_enabled}/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts (100%) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 77f2dba569460..4015b4f6666c8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -14,7 +14,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./get_prebuilt_timelines_status')); loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); - loadTestFile(require.resolve('./upgrade_prebuilt_rules')); loadTestFile(require.resolve('./fleet_integration')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); @@ -26,28 +25,5 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); - // loadTestFile(require.resolve('./bootstrap_prebuilt_rules')); - // loadTestFile(require.resolve('./get_prebuilt_rules_status')); - // loadTestFile(require.resolve('./get_prebuilt_timelines_status')); - // loadTestFile(require.resolve('./install_prebuilt_rules')); - // loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); - // loadTestFile(require.resolve('./upgrade_prebuilt_rules')); - // loadTestFile(require.resolve('./upgrade_prebuilt_rules_with_historical_versions')); - // loadTestFile(require.resolve('./fleet_integration')); - // loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.all_rules_mode')); - // loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.specific_rules_mode')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.single_line_string_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.scalar_array_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.multi_line_string_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.data_source_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.kql_query_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); - // loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); - loadTestFile(require.resolve('./review_prebuilt_rule_upgrade')); - loadTestFile(require.resolve('./diffable_rule_fields')); - loadTestFile(require.resolve('./upgrade_prebuilt_rules')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts index 6a97b85da8f12..d291c1c83fdf8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/alert_suppression.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts @@ -145,7 +145,7 @@ export function alertSuppressionField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function alertSuppressionField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function alertSuppressionField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts index 7bab3cb445c5c..5884c1ad87f37 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/anomaly_threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts @@ -145,7 +145,7 @@ export function anomalyThresholdField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function anomalyThresholdField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function anomalyThresholdField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts index ed248faf0d21c..4f4add7850235 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/building_block.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts @@ -143,7 +143,7 @@ export function buildingBlockField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -249,7 +249,7 @@ export function buildingBlockField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -357,7 +357,7 @@ export function buildingBlockField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts index 8173af1110c5c..b20ccca3dd4a9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/data_source.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts @@ -149,7 +149,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -260,7 +260,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -371,7 +371,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -804,7 +804,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -915,7 +915,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -1026,7 +1026,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts index 507fb514384b2..704fde10fe775 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/description.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts @@ -145,7 +145,7 @@ export function descriptionField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -256,7 +256,7 @@ export function descriptionField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -366,7 +366,7 @@ export function descriptionField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts index 33216e16ac564..04d538ad61c8a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/eql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts @@ -171,7 +171,7 @@ export function eqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -305,7 +305,7 @@ export function eqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -439,7 +439,7 @@ export function eqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts index e328196994c84..6d1ee7a2dcdc0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/esql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts @@ -163,7 +163,7 @@ export function esqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -291,7 +291,7 @@ export function esqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -419,7 +419,7 @@ export function esqlQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts index f9bc9ca1f6cfd..2b86af0f414b2 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/false_positives.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts @@ -145,7 +145,7 @@ export function falsePositivesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function falsePositivesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function falsePositivesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts index 3f29eacd9e83a..53d218cf2caf7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/history_window_start.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts @@ -145,7 +145,7 @@ export function historyWindowStartField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function historyWindowStartField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function historyWindowStartField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts index 748b8802742b8..619b3e0a95b95 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/investigation_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts @@ -145,7 +145,7 @@ export function investigationFieldsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function investigationFieldsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function investigationFieldsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts index d90f8380a0485..935d4ced71bc5 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.inline_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts @@ -182,7 +182,7 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -324,7 +324,7 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -466,7 +466,7 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts index 7b22a5d93849b..ba04dac707ebe 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/kql_query.saved_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts @@ -157,7 +157,7 @@ export function savedQueryKqlQueryField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -277,7 +277,7 @@ export function savedQueryKqlQueryField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -397,7 +397,7 @@ export function savedQueryKqlQueryField({ getService }: FtrProviderContext): voi }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts index 9ac6eb48bd6a9..a3747630c4ca5 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/machine_learning_job_id.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts @@ -145,7 +145,7 @@ export function machineLearningJobIdField({ getService }: FtrProviderContext): v }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function machineLearningJobIdField({ getService }: FtrProviderContext): v }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function machineLearningJobIdField({ getService }: FtrProviderContext): v }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts index 5d70b4a895d70..f8b29097301c3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/max_signals.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts @@ -145,7 +145,7 @@ export function maxSignalsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function maxSignalsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function maxSignalsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts index 3771ccc9276c8..021079e664e19 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/name.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts @@ -145,7 +145,7 @@ export function nameField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function nameField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function nameField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts index ade40eac6d0f8..cd03ca3c7bd9a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/new_terms_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts @@ -145,7 +145,7 @@ export function newTermsFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function newTermsFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function newTermsFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts index 59955707c0327..0011a0b17254c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/note.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts @@ -145,7 +145,7 @@ export function noteField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function noteField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function noteField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts index bfd2c9fb11376..6e1f8541b1d2d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/references.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts @@ -145,7 +145,7 @@ export function referencesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function referencesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function referencesField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts index f381fc9776a52..07414773dd933 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/related_integrations.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts @@ -212,7 +212,7 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -388,7 +388,7 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -556,7 +556,7 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts index 529caa48f55d8..80ca5355958d6 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/required_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts @@ -207,7 +207,7 @@ export function requiredFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -385,7 +385,7 @@ export function requiredFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -563,7 +563,7 @@ export function requiredFieldsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts index bc548f193b0f6..d1c9974b3376f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts @@ -145,7 +145,7 @@ export function riskScoreField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function riskScoreField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function riskScoreField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts index df91732b729f6..877c73fd43ee7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/risk_score_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts @@ -222,7 +222,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -414,7 +414,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -606,7 +606,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts index 218745b2fbfa2..c8b5823bc1304 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_name_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts @@ -145,7 +145,7 @@ export function ruleNameOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function ruleNameOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function ruleNameOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts index f6134f94a5a07..1f3f24260b9e9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/rule_schedule.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts @@ -173,7 +173,7 @@ export function ruleScheduleField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -313,7 +313,7 @@ export function ruleScheduleField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -453,7 +453,7 @@ export function ruleScheduleField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts index 7f25be9388b0c..71b23250df93f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/setup.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts @@ -145,7 +145,7 @@ export function setupField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function setupField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function setupField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts index faad4db39adc9..beafb919c2e14 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts @@ -147,7 +147,7 @@ export function severityField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -255,7 +255,7 @@ export function severityField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function severityField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts index 0b9c8783c18a8..eb3c32744d6c9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/severity_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts @@ -222,7 +222,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -414,7 +414,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -606,7 +606,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts index 9d4abd6e227dd..8112c1d02f229 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/tags.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts @@ -145,7 +145,7 @@ export function tagsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function tagsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function tagsField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts index c6c0a92fc7d02..e1a2141164c12 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts @@ -244,7 +244,7 @@ export function threatField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -460,7 +460,7 @@ export function threatField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -676,7 +676,7 @@ export function threatField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts index 6bf8e6272914b..c89edc4cb75a7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts @@ -145,7 +145,7 @@ export function threatIndexField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function threatIndexField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function threatIndexField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts index 20e073ddcd716..44a0d07c898a9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_indicator_path.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts @@ -145,7 +145,7 @@ export function threatIndicatorPathField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function threatIndicatorPathField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function threatIndicatorPathField({ getService }: FtrProviderContext): vo }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts index 1d9cff8197a37..49171debe25a3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts @@ -159,7 +159,7 @@ export function threatMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -280,7 +280,7 @@ export function threatMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -401,7 +401,7 @@ export function threatMappingField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts index 22a43facbdce6..a9ffe53e52dd1 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threat_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts @@ -173,7 +173,7 @@ export function threatQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -311,7 +311,7 @@ export function threatQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -449,7 +449,7 @@ export function threatQueryField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts index fe55b767cdb53..acbd074a23675 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts @@ -145,7 +145,7 @@ export function thresholdField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -254,7 +254,7 @@ export function thresholdField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -363,7 +363,7 @@ export function thresholdField({ getService }: FtrProviderContext): void { }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts index e03781d584681..de50f64d45f12 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timeline_template.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts @@ -151,7 +151,7 @@ export function timelineTemplateField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -266,7 +266,7 @@ export function timelineTemplateField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -381,7 +381,7 @@ export function timelineTemplateField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts index d68f20c96f882..e178c3a323af6 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/diffable_rule_fields/timestamp_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts @@ -145,7 +145,7 @@ export function timestampOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -253,7 +253,7 @@ export function timestampOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ @@ -361,7 +361,7 @@ export function timestampOverrideField({ getService }: FtrProviderContext): void }); }); - it('upgrades to MERGED version', async () => { + it('upgrades to MERGED value', async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, rules: [ diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts index ea0633cce9bbd..0b70a1536f8fc 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts @@ -12,7 +12,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./is_customized_calculation')); loadTestFile(require.resolve('./import_rules')); loadTestFile(require.resolve('./rules_export')); - loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.all_rules_mode')); - loadTestFile(require.resolve('./upgrade_perform_prebuilt_rules.specific_rules_mode')); + loadTestFile(require.resolve('./upgrade_prebuilt_rules')); + loadTestFile(require.resolve('./diffable_rule_fields')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts From f0f7b970bde46233d4212780e689893aaf62ee7d Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 3 Feb 2025 11:22:39 +0100 Subject: [PATCH 07/20] remove outdated integration tests --- .../trial_license_complete_tier/index.ts | 9 - ...eview_prebuilt_rules.data_source_fields.ts | 972 ------------- ..._review_prebuilt_rules.eql_query_fields.ts | 505 ------- ...review_prebuilt_rules.esql_query_fields.ts | 472 ------ ..._review_prebuilt_rules.kql_query_fields.ts | 1278 ----------------- ...prebuilt_rules.multi_line_string_fields.ts | 444 ------ ...ade_review_prebuilt_rules.number_fields.ts | 336 ----- ..._review_prebuilt_rules.rule_type_fields.ts | 362 ----- ...view_prebuilt_rules.scalar_array_fields.ts | 486 ------- ...rebuilt_rules.single_line_string_fields.ts | 375 ----- .../kql_query.inline_query.ts | 189 ++- 11 files changed, 128 insertions(+), 5300 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.data_source_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.multi_line_string_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.number_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.rule_type_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.scalar_array_fields.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.single_line_string_fields.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 4015b4f6666c8..e52b0dfc59cbe 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -15,15 +15,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.rule_type_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.number_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.single_line_string_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.scalar_array_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.multi_line_string_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.data_source_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.kql_query_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.data_source_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.data_source_fields.ts deleted file mode 100644 index b95208856a275..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.data_source_fields.ts +++ /dev/null @@ -1,972 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - AllFieldsDiff, - DataSourceType, - RuleUpdateProps, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - createHistoricalPrebuiltRuleAssetSavedObjects, - updateRule, - patchRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`data_source fields`, () => { - const getIndexRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - index: ['one', 'two', 'three'], - }), - ]; - - const getDataViewIdRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - data_view_id: 'A', - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - describe('when all versions are index patterns', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - index: ['one', 'three', 'two'], - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligable for update but data_source field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are data view id', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - data_view_id: 'A', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligable for update but data_source field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - describe('when current version is index pattern type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: ['one', 'two', 'four'], - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, do NOT update the related data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - data_view_id: 'A', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that data_source diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - target_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - merged_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when current version is data view id type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: undefined, - data_view_id: 'B', - } as RuleUpdateProps); - - // Increment the version of the installed rule, do NOT update the related data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - index: ['one', 'two', 'three'], - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that data_source diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - current_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - target_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - merged_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when current version is undefined', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, do NOT update the related data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - index: ['one', 'two', 'three'], - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that data_source diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - current_version: undefined, - target_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - merged_version: undefined, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - describe('when target version is index pattern type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'four'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - target_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - merged_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when target version is data view id type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - data_view_id: 'B', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - current_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - target_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - merged_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - describe('when current and target version are index pattern type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: ['one', 'two', 'four'], - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'four'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains data_source field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - target_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - merged_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when current and target version are data view id type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: undefined, - data_view_id: 'B', - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - data_view_id: 'B', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains data_source field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - current_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - target_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - merged_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - describe('when just current and target versions are index patterns', () => { - it('should show a solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: ['one', 'one', 'two', 'three'], - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'five'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - index_patterns: ['one', 'one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - target_version: { - index_patterns: ['one', 'two', 'five'], - type: DataSourceType.index_patterns, - }, - merged_version: { - index_patterns: ['one', 'two', 'three', 'five'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are index patterns', () => { - it('should show a solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getIndexRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - index: ['one', 'two', 'four'], - }); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'five'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - index_patterns: ['one', 'two', 'three'], - type: DataSourceType.index_patterns, - }, - current_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - target_version: { - index_patterns: ['one', 'two', 'five'], - type: DataSourceType.index_patterns, - }, - merged_version: { - index_patterns: ['one', 'two', 'four', 'five'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are data view id types', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: undefined, - data_view_id: 'B', - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - data_view_id: 'C', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - target_version: { - data_view_id: 'C', - type: DataSourceType.data_view, - }, - merged_version: { - data_view_id: 'B', - type: DataSourceType.data_view, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when current and target versions are different data types', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: ['one', 'two', 'four'], - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - data_view_id: 'C', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - target_version: { - data_view_id: 'C', - type: DataSourceType.data_view, - }, - merged_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when current version is undefined', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getDataViewIdRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - data_view_id: 'C', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - base_version: { - data_view_id: 'A', - type: DataSourceType.data_view, - }, - current_version: undefined, - target_version: { - data_view_id: 'C', - type: DataSourceType.data_view, - }, - merged_version: undefined, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getIndexRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Increment the version of the installed rule, but keep data_source field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'three'], // unchanged - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain data_source field (tags is not present, since scenario -AA is not included in response) - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getIndexRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a data_source field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - index: ['one', 'two', 'four'], - data_view_id: undefined, - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a data_source field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - index: ['one', 'two', 'five'], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and data_source field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.data_source).toEqual({ - current_version: { - index_patterns: ['one', 'two', 'four'], - type: DataSourceType.index_patterns, - }, - target_version: { - index_patterns: ['one', 'two', 'five'], - type: DataSourceType.index_patterns, - }, - merged_version: { - index_patterns: ['one', 'two', 'five'], - type: DataSourceType.index_patterns, - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // tags - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts deleted file mode 100644 index 6c49f8722abd4..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts +++ /dev/null @@ -1,505 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - AllFieldsDiff, - RuleUpdateProps, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - createHistoricalPrebuiltRuleAssetSavedObjects, - updateRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`eql_query fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'eql', - query: 'query where true', - language: 'eql', - filters: [], - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where true', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but eql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should trim all whitespace before version comparison', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an eql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'eql', - query: '\nquery where true\n', - language: 'eql', - filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: '\nquery where true', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but eql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an eql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where true', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that eql_query diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toEqual({ - base_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - target_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toEqual({ - base_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - target_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an eql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains eql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toEqual({ - base_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - target_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an eql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'eql', - query: 'query where true', - language: 'eql', - filters: [{ field: 'query' }], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and eql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toEqual({ - base_version: { - query: 'query where true', - language: 'eql', - filters: [], - }, - current_version: { - query: 'query where true', - language: 'eql', - filters: [{ field: 'query' }], - }, - target_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'query where true', - language: 'eql', - filters: [{ field: 'query' }], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a v2 rule asset to make the upgrade possible, but keep eql_query field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'query where true', - language: 'eql', - filters: [], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain eql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize an eql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'eql', - query: 'query where false', - language: 'eql', - filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'eql', - query: 'new query where true', - language: 'eql', - filters: [], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and eql_query field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.eql_query).toEqual({ - current_version: { - query: 'query where false', - language: 'eql', - filters: [], - }, - target_version: { - query: 'new query where true', - language: 'eql', - filters: [], - }, - merged_version: { - query: 'new query where true', - language: 'eql', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // version + query - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // query - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts deleted file mode 100644 index d8329ce023ea6..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts +++ /dev/null @@ -1,472 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - AllFieldsDiff, - RuleUpdateProps, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - createHistoricalPrebuiltRuleAssetSavedObjects, - updateRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`esql_query fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'esql', - query: 'FROM query WHERE true', - language: 'esql', - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM query WHERE true', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but esql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should trim all whitespace before version comparison', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an esql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'esql', - query: '\tFROM query WHERE true\t', - language: 'esql', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: '\n\nFROM query WHERE true\n\n', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but esql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an esql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM query WHERE true', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that esql_query diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toEqual({ - base_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - current_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - target_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - merged_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toEqual({ - base_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - current_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - target_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - merged_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an esql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains esql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toEqual({ - base_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - current_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - target_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - merged_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize an esql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM new query WHERE true', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and esql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toEqual({ - base_version: { - query: 'FROM query WHERE true', - language: 'esql', - }, - current_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - target_version: { - query: 'FROM new query WHERE true', - language: 'esql', - }, - merged_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a v2 rule asset to make the upgrade possible, but keep esql_query field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM query WHERE true', - language: 'esql', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain esql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize an esql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'esql', - query: 'FROM query WHERE false', - language: 'esql', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - query: 'FROM new query WHERE true', - language: 'esql', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and esql_query field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.esql_query).toEqual({ - current_version: { - query: 'FROM query WHERE false', - language: 'esql', - }, - target_version: { - query: 'FROM new query WHERE true', - language: 'esql', - }, - merged_version: { - query: 'FROM new query WHERE true', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // query - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts deleted file mode 100644 index 50bdb83744f04..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts +++ /dev/null @@ -1,1278 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - AllFieldsDiff, - KqlQueryType, - RuleUpdateProps, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { - getPrebuiltRuleMock, - getPrebuiltThreatMatchRuleMock, -} from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; -import { PrebuiltRuleAsset } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - createHistoricalPrebuiltRuleAssetSavedObjects, - updateRule, - patchRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`kql_query fields`, () => { - const getQueryRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [], - }), - ]; - - const getSavedQueryRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'saved_query', - saved_id: 'saved-query-id', - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - describe('when all versions are inline query types', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are saved query types', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getSavedQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all query versions have different surrounding whitespace', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'query', - query: '\nquery string = true', - language: 'kuery', - filters: [], - saved_id: undefined, - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true\n', - language: 'kuery', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all query versions have filters with alias fields set to null', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [ - { - meta: { - negate: false, - disabled: false, - type: 'phrase', - key: 'test', - params: { - query: 'value', - }, - }, - query: { - term: { - field: 'value', - }, - }, - }, - ], - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [ - { - meta: { - alias: null, - negate: false, - disabled: false, - type: 'phrase', - key: 'test', - params: { - query: 'value', - }, - }, - query: { - term: { - field: 'value', - }, - }, - }, - ], - saved_id: undefined, - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [ - { - meta: { - negate: false, - disabled: false, - type: 'phrase', - key: 'test', - params: { - query: 'value', - }, - }, - query: { - term: { - field: 'value', - }, - }, - }, - ], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - describe('when current version is inline query type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getSavedQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [], - saved_id: undefined, - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that kql_query diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // `type` is considered to be a conflict - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when current version is saved query type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - query: undefined, - language: undefined, - filters: undefined, - saved_id: 'saved-query-id', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that kql_query diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // `type` is considered to be a conflict - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - describe('when all versions are inline query type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = false', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are saved query type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getSavedQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'new-saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - current_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - target_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - merged_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - describe('when all versions are inline query type', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - query: 'query string = false', - }); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = false', - language: 'kuery', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains kql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are saved query types', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getSavedQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - saved_id: 'new-saved-query-id', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'new-saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains kql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - current_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - target_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - merged_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - describe('when current version is different type than base and target', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - query: undefined, - language: undefined, - filters: undefined, - saved_id: 'saved-query-id', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = false', - language: 'kuery', - filters: [], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is also considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // `type` is also considered to be a conflict - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(2); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when all versions are inline query type', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - query: 'query string = false', - }); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [{ field: 'query' }], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [{ field: 'query' }], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when all versions are saved query type', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects( - es, - getSavedQueryRuleAssetSavedObjects() - ); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - saved_id: 'new-saved-query-id', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'even-newer-saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'saved-query-id', - }, - current_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - target_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'even-newer-saved-query-id', - }, - merged_version: { - type: KqlQueryType.saved_query, - saved_query_id: 'new-saved-query-id', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule type is threat match', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - ...getPrebuiltThreatMatchRuleMock(), - threat_filters: [], - } as PrebuiltRuleAsset), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a threat_query on the installed rule - await updateRule(supertest, { - ...getPrebuiltThreatMatchRuleMock(), - rule_id: 'rule-1', - threat_query: '*', - threat_filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a threat_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - ...getPrebuiltThreatMatchRuleMock(), - threat_query: `*:'new query'`, - threat_filters: [], - version: 2, - } as PrebuiltRuleAsset), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and threat_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.threat_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: '*:*', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: '*', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: `*:'new query'`, - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: '*', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule type is threshold', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'threshold', - query: 'query string = true', - threshold: { - field: 'some.field', - value: 4, - }, - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'threshold', - query: 'query string = false', - threshold: { - field: 'some.field', - value: 4, - }, - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'threshold', - query: 'new query string = true', - threshold: { - field: 'some.field', - value: 4, - }, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'new query string = true', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule type is new_terms', () => { - it('should show a non-solvable conflict in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - type: 'new_terms', - query: 'query string = true', - new_terms_fields: ['user.name'], - history_window_start: 'now-7d', - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'new_terms', - query: 'query string = false', - new_terms_fields: ['user.name'], - history_window_start: 'now-7d', - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'new_terms', - query: 'new query string = true', - new_terms_fields: ['user.name'], - history_window_start: 'now-7d', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - base_version: { - type: KqlQueryType.inline_query, - query: 'query string = true', - language: 'kuery', - filters: [], - }, - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'new query string = true', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getQueryRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a v2 rule asset to make the upgrade possible, but keep kql_query field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'query string = true', - language: 'kuery', - filters: [], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain kql_query field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getQueryRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a kql_query field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'query', - query: 'query string = false', - language: 'kuery', - filters: [], - } as RuleUpdateProps); - - // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - query: 'new query string = true', - language: 'kuery', - filters: [], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and kql_query field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; - expect(fieldDiffObject.kql_query).toEqual({ - current_version: { - type: KqlQueryType.inline_query, - query: 'query string = false', - language: 'kuery', - filters: [], - }, - target_version: { - type: KqlQueryType.inline_query, - query: 'new query string = true', - language: 'kuery', - filters: [], - }, - merged_version: { - type: KqlQueryType.inline_query, - query: 'new query string = true', - language: 'kuery', - filters: [], - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // query - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.multi_line_string_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.multi_line_string_fields.ts deleted file mode 100644 index 23bfd08f5b520..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.multi_line_string_fields.ts +++ /dev/null @@ -1,444 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { - TEXT_XL_A, - TEXT_XL_B, - TEXT_XL_C, - TEXT_XL_MERGED, -} from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/logic/diff/calculation/algorithms/multi_line_string_diff_algorithm.mock'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`multi line string fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - description: 'My description.\nThis is a second line.', - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - description: 'My description.\nThis is a second line.', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible - // for update but multi-line string field (description) is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // version - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My GREAT description.\nThis is a second line.', - }); - - // Increment the version of the installed rule, do NOT update the related multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - description: 'My description.\nThis is a second line.', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that multi line string diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: 'My description.\nThis is a second line.', - current_version: 'My GREAT description.\nThis is a second line.', - target_version: 'My description.\nThis is a second line.', - merged_version: 'My GREAT description.\nThis is a second line.', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My GREAT description.\nThis is a second line.', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: 'My description.\nThis is a second line.', - current_version: 'My description.\nThis is a second line.', - target_version: 'My GREAT description.\nThis is a second line.', - merged_version: 'My GREAT description.\nThis is a second line.', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My GREAT description.\nThis is a second line.', - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My GREAT description.\nThis is a second line.', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: 'My description.\nThis is a second line.', - current_version: 'My GREAT description.\nThis is a second line.', - target_version: 'My GREAT description.\nThis is a second line.', - merged_version: 'My GREAT description.\nThis is a second line.', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - describe('when all versions are mergable', () => { - it('should show in the upgrade/_review API response with a solvable conflict', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My GREAT description.\nThis is a second line.', - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My description.\nThis is a second line, now longer.', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and multi line string field update has no conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: 'My description.\nThis is a second line.', - current_version: 'My GREAT description.\nThis is a second line.', - target_version: 'My description.\nThis is a second line, now longer.', - merged_version: 'My GREAT description.\nThis is a second line, now longer.', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should handle long multi-line strings without timing out', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - description: TEXT_XL_A, - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: TEXT_XL_B, - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: TEXT_XL_C, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and multi line string field update has no conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: TEXT_XL_A, - current_version: TEXT_XL_B, - target_version: TEXT_XL_C, - merged_version: TEXT_XL_MERGED, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when all versions are not mergable', () => { - it('should show in the upgrade/_review API response with a non-solvable conflict', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My GREAT description.\nThis is a third line.', - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My EXCELLENT description.\nThis is a fourth.', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and multi line string field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - base_version: 'My description.\nThis is a second line.', - current_version: 'My GREAT description.\nThis is a third line.', - target_version: 'My EXCELLENT description.\nThis is a fourth.', - merged_version: 'My GREAT description.\nThis is a third line.', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My description.\nThis is a second line.', - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My description.\nThis is a second line.', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain multi line string field, since -AA is treated as AAA - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a multi line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - description: 'My description.\nThis is a second line.', - }); - - // Increment the version of the installed rule, update a multi line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - description: 'My GREAT description.\nThis is a second line.', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and multi line string field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.description).toEqual({ - current_version: 'My description.\nThis is a second line.', - target_version: 'My GREAT description.\nThis is a second line.', - merged_version: 'My GREAT description.\nThis is a second line.', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.number_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.number_fields.ts deleted file mode 100644 index bd059ec137a96..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.number_fields.ts +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`number fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1, risk_score: 1 }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - risk_score: 1, - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible - // for update but number field (risk_score) is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // version - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a number field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - risk_score: 2, - }); - - // Increment the version of the installed rule, do NOT update the related number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - risk_score: 1, - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that number diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toEqual({ - base_version: 1, - current_version: 2, - target_version: 1, - merged_version: 2, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - risk_score: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toEqual({ - base_version: 1, - current_version: 1, - target_version: 2, - merged_version: 2, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a number field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - risk_score: 2, - }); - - // Increment the version of the installed rule, update a number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - risk_score: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains number field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toEqual({ - base_version: 1, - current_version: 2, - target_version: 2, - merged_version: 2, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a number field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - risk_score: 2, - }); - - // Increment the version of the installed rule, update a number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - risk_score: 3, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and number field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toEqual({ - base_version: 1, - current_version: 2, - target_version: 3, - merged_version: 2, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Increment the version of the installed rule with the number field maintained - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - risk_score: 1, - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain the risk_score number field, since -AA is treated as AAA - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a number field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - risk_score: 2, - }); - - // Increment the version of the installed rule, update a number field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - risk_score: 3, - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and number field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.risk_score).toEqual({ - current_version: 2, - target_version: 3, - merged_version: 3, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.rule_type_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.rule_type_fields.ts deleted file mode 100644 index 3f6784108487c..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.rule_type_fields.ts +++ /dev/null @@ -1,362 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - RuleUpdateProps, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, - updateRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`rule type fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1, type: 'query' }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update - // but type field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a type field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - query: undefined, - language: undefined, - filters: undefined, - saved_id: 'saved-query-id', - } as RuleUpdateProps); - - // Increment the version of the installed rule, do NOT update the related type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that type diff field - // is returned but field does not have an update, and the merge outcome is "Target" - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toEqual({ - base_version: 'query', - current_version: 'saved_query', - target_version: 'query', - merged_version: 'query', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // version field counts as upgraded - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'even-newer-saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toEqual({ - base_version: 'query', - current_version: 'query', - target_version: 'saved_query', - merged_version: 'saved_query', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(3); // version and query fields also have updates - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a type field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - query: undefined, - language: undefined, - filters: undefined, - saved_id: 'saved-query-id', - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'saved-query-id', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toEqual({ - base_version: 'query', - current_version: 'saved_query', - target_version: 'saved_query', - merged_version: 'saved_query', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a type field on the installed rule - await updateRule(supertest, { - ...getPrebuiltRuleMock(), - rule_id: 'rule-1', - type: 'saved_query', - query: undefined, - language: undefined, - filters: undefined, - saved_id: 'saved-query-id', - } as RuleUpdateProps); - - // Increment the version of the installed rule, update a type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'esql', - language: 'esql', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and type field update has NON_SOLVABLE conflict, and merged version is TARGET - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toEqual({ - base_version: 'query', - current_version: 'saved_query', - target_version: 'esql', - merged_version: 'esql', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(4); // version + type + kql_query all considered updates - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // type + kql_query both considered conflicts - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(2); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Increment the version of the installed rule, but keep type field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'query', // unchanged - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain type field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a type field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - type: 'query', - }); - - // Increment the version of the installed rule, update a type field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - type: 'saved_query', - saved_id: 'saved-query-id', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and type field update does have a non-solvable conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.type).toEqual({ - current_version: 'query', - target_version: 'saved_query', - merged_version: 'saved_query', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(3); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // type + query are all considered conflicts - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.scalar_array_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.scalar_array_fields.ts deleted file mode 100644 index 881e8e6122175..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.scalar_array_fields.ts +++ /dev/null @@ -1,486 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`scalar array fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - tags: ['one', 'two', 'three'], - }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - tags: ['one', 'three', 'two'], - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligable for update but scalar array field is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['one', 'two', 'four'], - }); - - // Increment the version of the installed rule, do NOT update the related scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - tags: ['one', 'two', 'three'], - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that scalar array diff field is returned but field does not have an update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'three'], - current_version: ['one', 'two', 'four'], - target_version: ['one', 'two', 'three'], - merged_version: ['one', 'two', 'four'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'four'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'three'], - current_version: ['one', 'two', 'three'], - target_version: ['one', 'two', 'four'], - merged_version: ['one', 'two', 'four'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['one', 'two', 'four'], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'four'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains scalar array field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'three'], - current_version: ['one', 'two', 'four'], - target_version: ['one', 'two', 'four'], - merged_version: ['one', 'two', 'four'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['one', 'two', 'four'], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'five'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and scalar array field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'three'], - current_version: ['one', 'two', 'four'], - target_version: ['one', 'two', 'five'], - merged_version: ['one', 'two', 'four', 'five'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should compare values after deduplication', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - tags: ['one', 'two', 'two'], - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['two', 'one', 'three'], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['three', 'three', 'one'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and scalar array field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'two'], - current_version: ['two', 'one', 'three'], - target_version: ['three', 'three', 'one'], - merged_version: ['one', 'three'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should compare values sensitive of case', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 1, - tags: ['ONE', 'TWO'], - }), - ]); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['one', 'ONE'], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['ONE', 'THREE'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and scalar array field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['ONE', 'TWO'], - current_version: ['one', 'ONE'], - target_version: ['ONE', 'THREE'], - merged_version: ['ONE', 'one', 'THREE'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should handle empty arrays', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: [], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'five'], - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and scalar array field update has conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - base_version: ['one', 'two', 'three'], - current_version: [], - target_version: ['one', 'two', 'five'], - merged_version: ['five'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Increment the version of the installed rule, but keep scalar array field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'three'], // unchanged - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain scalar array field (tags is not present, since scenario -AA is not included in response) - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a scalar array field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - tags: ['one', 'two', 'four'], - }); - - // Increment the version of the installed rule, update a scalar array field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - tags: ['one', 'two', 'five'], - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and scalar array field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.tags).toEqual({ - current_version: ['one', 'two', 'four'], - target_version: ['one', 'two', 'five'], - merged_version: ['one', 'two', 'five'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // tags - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.single_line_string_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.single_line_string_fields.ts deleted file mode 100644 index 6d32d8df7bc72..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.single_line_string_fields.ts +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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 expect from 'expect'; -import { - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`single line string fields`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1, name: 'A' }), - ]; - - describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, do NOT update the related single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - name: 'A', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update - // but single line string field (name) is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should trim all whitespace before version comparison', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a single line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - name: 'A\n', - }); - - // Increment the version of the installed rule, do NOT update the related single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - name: '\nA', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update - // but single line string field (name) is NOT returned - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a single line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - name: 'B', - }); - - // Increment the version of the installed rule, do NOT update the related single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - name: 'A', - version: 2, - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that single line string diff field - // is returned but field does not have an update, and the merge outcome is "Current" - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toEqual({ - base_version: 'A', - current_version: 'B', - target_version: 'A', - merged_version: 'B', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update but does not have a custom value - scenario AAB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Increment the version of the installed rule, update a single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - name: 'B', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toEqual({ - base_version: 'A', - current_version: 'A', - target_version: 'B', - merged_version: 'B', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a single line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - name: 'B', - }); - - // Increment the version of the installed rule, update a single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - name: 'B', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toEqual({ - base_version: 'A', - current_version: 'B', - target_version: 'B', - merged_version: 'B', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario ABC', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a single line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - name: 'B', - }); - - // Increment the version of the installed rule, update a single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - name: 'C', - }), - ]; - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and single line string field update has NON_SOLVABLE conflict, and merged version is CURRENT - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toEqual({ - base_version: 'A', - current_version: 'B', - target_version: 'C', - merged_version: 'B', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); - }); - }); - - describe('when rule base version does not exist', () => { - describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { - it('should not show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Increment the version of the installed rule, but keep single line string field unchanged - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - name: 'A', // unchanged - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // but does NOT contain single line string field - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toBeUndefined(); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - - describe('when rule field has an update and a custom value that are different - scenario -AB', () => { - it('should show in the upgrade/_review API response', async () => { - // Install base prebuilt detection rule - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Customize a single line string field on the installed rule - await patchRule(supertest, log, { - rule_id: 'rule-1', - name: 'B', - }); - - // Increment the version of the installed rule, update a single line string field, and create the new rule assets - const updatedRuleAssetSavedObjects = [ - createRuleAssetSavedObject({ - rule_id: 'rule-1', - version: 2, - name: 'C', - }), - ]; - await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update - // and single line string field update does not have a conflict - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - expect(reviewResponse.rules[0].diff.fields.name).toEqual({ - current_version: 'B', - target_version: 'C', - merged_version: 'C', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }); - - expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); - expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // name is considered as a conflict - expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts index 935d4ced71bc5..7173790ab48ec 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts @@ -37,79 +37,146 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo for (const ruleType of RULE_TYPES) { describe('"kql_query" with inline query', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', + describe('without filters', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, }, - }, - deps, + deps, + }); }); - }); - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); + it('does NOT return upgrade review', async () => { + const response = await reviewPrebuiltRulesToUpgrade(supertest); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); }); - }); - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], + it('upgrades to RESOLVED value', async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + fields: { + kql_query: { + pick_version: 'RESOLVED', + resolved_value: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, }, }, }, - }, - ], - }); + ], + }); - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); - expect(response.results.updated[0]).toMatchObject({ - type: ruleType, - query: 'resolved:*', - language: 'kuery', + expect(response.results.updated[0]).toMatchObject({ + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }); + expect(upgradedRule.body).toMatchObject({ + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }); }); - expect(upgradedRule.body).toMatchObject({ - type: ruleType, - query: 'resolved:*', - language: 'kuery', + }); + + describe('with filters', () => { + describe('and filters have "alias" field set to null for installed rules', () => { + it('does NOT return upgrade review', async () => { + const FILTER = { + meta: { + negate: false, + disabled: false, + type: 'phrase', + key: 'test', + params: { + query: 'value', + }, + }, + query: { + term: { + field: 'value', + }, + }, + }; + + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + filters: [FILTER], + }, + patch: { + type: ruleType, + filters: [ + { + ...FILTER, + meta: { + ...FILTER.meta, + alias: null, + }, + }, + ], + }, + upgrade: { + type: ruleType, + filters: [FILTER], + }, + }, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 1, + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 1, + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(response.rules[0].diff.fields).not.toMatchObject({ + kql_query: expect.anything(), + }); + }); }); }); }); From 41553292cc9fa1d640f1bb2f98e6f723c9f8e4f1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 3 Feb 2025 12:20:33 +0100 Subject: [PATCH 08/20] extend bulk upgrade integration tests --- .../bulk_upgrade_all_prebuilt_rules.ts | 2 +- .../bulk_upgrade_selected_prebuilt_rules.ts | 453 ++++++++++-------- .../upgrade_one_prebuilt_rule.ts | 6 +- 3 files changed, 255 insertions(+), 206 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts index 2ed9de92ad6e0..7f03101502f61 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_all_prebuilt_rules.ts @@ -167,7 +167,7 @@ export function bulkUpgradeAllPrebuiltRules({ getService }: FtrProviderContext): ); }); - it('DOES NOT upgrade in case of conflicts when is MERGED', async () => { + it('UNABLE to upgrade in case of conflicts when is MERGED', async () => { await setUpRuleUpgrade({ assets: [ { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts index 0beb7d1074aed..fc2f083a180ef 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/bulk_upgrade_selected_prebuilt_rules.ts @@ -23,88 +23,141 @@ export function bulkUpgradeSelectedPrebuiltRules({ getService }: FtrProviderCont describe('selected rules', () => { describe('with historical versions', () => { - const TEST_DATA = [ - { - globalPickVersion: 'BASE', - rulePickVersion: undefined, - expectedPickVersion: 'BASE', - expectedTags: ['tagA'], - }, - { - globalPickVersion: 'CURRENT', - rulePickVersion: undefined, - expectedPickVersion: 'CURRENT', - expectedTags: ['tagB'], - }, - { - globalPickVersion: 'TARGET', - rulePickVersion: undefined, - expectedPickVersion: 'TARGET', - expectedTags: ['tagC'], - }, - { - globalPickVersion: undefined, - rulePickVersion: 'BASE', - expectedPickVersion: 'BASE', - expectedTags: ['tagA'], - }, - { - globalPickVersion: undefined, - rulePickVersion: 'CURRENT', - expectedPickVersion: 'CURRENT', - expectedTags: ['tagB'], - }, - { - globalPickVersion: undefined, - rulePickVersion: 'TARGET', - expectedPickVersion: 'TARGET', - expectedTags: ['tagC'], - }, - { - globalPickVersion: 'BASE', - rulePickVersion: 'CURRENT', - expectedPickVersion: 'CURRENT', - expectedTags: ['tagB'], - }, - { - globalPickVersion: 'BASE', - rulePickVersion: 'TARGET', - expectedPickVersion: 'TARGET', - expectedTags: ['tagC'], - }, - { - globalPickVersion: 'CURRENT', - rulePickVersion: 'BASE', - expectedPickVersion: 'BASE', - expectedTags: ['tagA'], - }, - { - globalPickVersion: 'CURRENT', - rulePickVersion: 'TARGET', - expectedPickVersion: 'TARGET', - expectedTags: ['tagC'], - }, - { - globalPickVersion: 'TARGET', - rulePickVersion: 'BASE', - expectedPickVersion: 'BASE', - expectedTags: ['tagA'], - }, - { - globalPickVersion: 'TARGET', - rulePickVersion: 'CURRENT', - expectedPickVersion: 'CURRENT', - expectedTags: ['tagB'], - }, - ] as const; + describe('without customizations', () => { + beforeEach(async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + type: 'query', + name: 'Initial name', + tags: ['tagA'], + rule_id: 'rule_1', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Updated name', + tags: ['tagC'], + rule_id: 'rule_1', + version: 2, + }, + }, + { + installed: { + type: 'query', + name: 'Initial name', + tags: ['tagA'], + rule_id: 'rule_2', + version: 1, + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Updated name', + tags: ['tagC'], + rule_id: 'rule_2', + version: 2, + }, + }, + // Rule rule_id: 'rule_3' isn't selected for upgrade + { + installed: { + type: 'query', + name: 'Initial name', + tags: ['tagA'], + rule_id: 'rule_3', + version: 1, + }, + patch: { + rule_id: 'rule_3', + name: 'Customized name', + tags: ['tagB'], + }, + upgrade: { + type: 'query', + name: 'Updated name', + tags: ['tagC'], + rule_id: 'rule_3', + version: 2, + }, + }, + ], + deps, + }); + }); + + for (const { pickVersion, expectedName, expectedTags } of [ + { + pickVersion: 'BASE', + expectedName: 'Initial name', + expectedTags: ['tagA'], + }, + { + pickVersion: 'CURRENT', + expectedName: 'Initial name', + expectedTags: ['tagA'], + }, + { + pickVersion: 'TARGET', + expectedName: 'Updated name', + expectedTags: ['tagC'], + }, + { + pickVersion: 'MERGED', + expectedName: 'Updated name', + expectedTags: ['tagC'], + }, + ] as const) { + it(`upgrades with is MERGED`, async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: 'rule_1', + revision: 0, + version: 2, + pick_version: pickVersion, + }, + { + rule_id: 'rule_2', + revision: 0, + version: 2, + pick_version: pickVersion, + }, + ], + }); - for (const { - globalPickVersion, - rulePickVersion, - expectedPickVersion, - expectedTags, - } of TEST_DATA) { - it(`upgrades to ${expectedPickVersion} version when "globalPickVersion: ${globalPickVersion}" and "rulePickVersion: ${rulePickVersion}"`, async () => { + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + name: expectedName, + tags: expectedTags, + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + name: expectedName, + tags: expectedTags, + }), + ]) + ); + }); + } + }); + + describe('with customizations resulting in conflicts', () => { + beforeEach(async () => { await setUpRuleUpgrade({ assets: [ { @@ -164,144 +217,140 @@ export function bulkUpgradeSelectedPrebuiltRules({ getService }: FtrProviderCont ], deps, }); + }); + + const TEST_DATA = [ + { + globalPickVersion: 'BASE', + rulePickVersion: undefined, + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: undefined, + expectedTags: ['tagB'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: undefined, + expectedTags: ['tagC'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'CURRENT', + expectedPickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + { + globalPickVersion: undefined, + rulePickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'BASE', + rulePickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + { + globalPickVersion: 'BASE', + rulePickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'CURRENT', + rulePickVersion: 'TARGET', + expectedTags: ['tagC'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: 'BASE', + expectedTags: ['tagA'], + }, + { + globalPickVersion: 'TARGET', + rulePickVersion: 'CURRENT', + expectedTags: ['tagB'], + }, + ] as const; + + for (const { globalPickVersion, rulePickVersion, expectedTags } of TEST_DATA) { + it(`upgrades rule when "globalPickVersion is ${globalPickVersion}" and "rulePickVersion is ${rulePickVersion}"`, async () => { + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + pick_version: globalPickVersion, + rules: [ + { + rule_id: 'rule_1', + revision: 1, + version: 2, + pick_version: rulePickVersion, + }, + { + rule_id: 'rule_2', + revision: 1, + version: 2, + pick_version: rulePickVersion, + }, + ], + }); + expect(response.summary).toMatchObject({ + total: 2, + succeeded: 2, + skipped: 0, + failed: 0, + }); + expect(response.results.updated).toHaveLength(2); + expect(response.results.updated).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + rule_id: 'rule_1', + version: 2, + tags: expectedTags, + }), + expect.objectContaining({ + rule_id: 'rule_2', + version: 2, + tags: expectedTags, + }), + ]) + ); + }); + } + + it(`UNABLE to upgrade rules when is MERGED`, async () => { const response = await performUpgradePrebuiltRules(es, supertest, { mode: ModeEnum.SPECIFIC_RULES, - pick_version: globalPickVersion, rules: [ { rule_id: 'rule_1', - revision: 1, + revision: 0, version: 2, - pick_version: rulePickVersion, + pick_version: 'MERGED', }, { rule_id: 'rule_2', - revision: 1, + revision: 0, version: 2, - pick_version: rulePickVersion, + pick_version: 'MERGED', }, ], }); expect(response.summary).toMatchObject({ - total: 2, - succeeded: 2, - skipped: 0, - failed: 0, + failed: 2, }); - expect(response.results.updated).toHaveLength(2); - expect(response.results.updated).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - rule_id: 'rule_1', - version: 2, - tags: expectedTags, - }), - expect.objectContaining({ - rule_id: 'rule_2', - version: 2, - tags: expectedTags, - }), - ]) - ); }); - } - - it(`upgrades to TARGET when is MERGED and there are no conflicts`, async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - type: 'query', - tags: ['tagA'], - rule_id: 'rule_1', - version: 1, - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagC'], - rule_id: 'rule_1', - version: 2, - }, - }, - { - installed: { - type: 'query', - tags: ['tagA'], - rule_id: 'rule_2', - version: 1, - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagC'], - rule_id: 'rule_2', - version: 2, - }, - }, - { - installed: { - type: 'query', - tags: ['tagA'], - rule_id: 'rule_3', - version: 1, - }, - patch: { - rule_id: 'rule_3', - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - rule_id: 'rule_3', - version: 2, - }, - }, - ], - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 0, - version: 2, - pick_version: 'MERGED', - }, - { - rule_id: 'rule_2', - revision: 0, - version: 2, - pick_version: 'MERGED', - }, - ], - }); - - expect(response.summary).toMatchObject({ - total: 2, - succeeded: 2, - skipped: 0, - failed: 0, - }); - expect(response.results.updated).toHaveLength(2); - expect(response.results.updated).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - rule_id: 'rule_1', - version: 2, - tags: ['tagC'], - }), - expect.objectContaining({ - rule_id: 'rule_2', - version: 2, - tags: ['tagC'], - }), - ]) - ); }); }); @@ -385,7 +434,7 @@ export function bulkUpgradeSelectedPrebuiltRules({ getService }: FtrProviderCont } for (const pickVersion of ['BASE', 'MERGED'] as const) { - it(`UNABLE to upgrade to ${pickVersion} version`, async () => { + it(`UNABLE to upgrade rules when is ${pickVersion}`, async () => { await setUpRuleUpgrade({ assets: [ { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts index 7afc248628b80..55ebc258d362f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts @@ -23,7 +23,7 @@ export function upgradeOnePrebuiltRule({ getService }: FtrProviderContext): void log, }; - describe('one rule with historical version', () => { + describe('one rule with historical versions', () => { const RULE_TYPES = [ 'query', 'saved_query', @@ -216,7 +216,7 @@ export function upgradeOnePrebuiltRule({ getService }: FtrProviderContext): void } for (const pickVersion of ['BASE', 'CURRENT', 'MERGED'] as const) { - it(`DOES NOT upgrade rule when rule type changed and is ${pickVersion}`, async () => { + it(`UNABLE to upgrade rule when rule type changed and is ${pickVersion}`, async () => { await setUpRuleUpgrade({ assets: { installed: { @@ -262,7 +262,7 @@ export function upgradeOnePrebuiltRule({ getService }: FtrProviderContext): void } for (const ruleType of RULE_TYPES) { - it(`DOES NOT upgrade non-upgradable fields for ${ruleType} rule`, async () => { + it(`UNABLE to upgrade non-upgradable fields for ${ruleType} rule`, async () => { const NON_UPGRADABLE_FIELDS = { enabled: true, exceptions_list: [ From 7a765b3c22b995adc80e7139147927c3b095ec26 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 3 Feb 2025 12:34:44 +0100 Subject: [PATCH 09/20] add rule upgrade review integration tests --- .../trial_license_complete_tier/index.ts | 1 - .../upgrade_review_prebuilt_rules.stats.ts | 131 ------ .../diffable_rule_fields/index.ts | 3 +- .../customization_enabled/index.ts | 1 + .../preview_prebuilt_rules_upgrade.ts | 400 ++++++++++++++++++ .../upgrade_prebuilt_rules/index.ts | 3 +- 6 files changed, 403 insertions(+), 136 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index e52b0dfc59cbe..0b57697c483b5 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -15,6 +15,5 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./install_prebuilt_rules')); loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); - loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts deleted file mode 100644 index 74010578da9f3..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.stats.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 expect from 'expect'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - installPrebuiltRules, - // createPrebuiltRuleAssetSavedObjects, - reviewPrebuiltRulesToUpgrade, - // patchRule, - createHistoricalPrebuiltRuleAssetSavedObjects, - patchRule, -} from '../../../../utils'; -import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`the endpoint stats -`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1, name: 'A' }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1, name: 'A' }), - createRuleAssetSavedObject({ rule_id: 'rule-3', version: 1, name: 'A' }), - ]; - - it('should show how many rules have upgrades', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'A', - version: 2, - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should show how many rules have updates with conflicts', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rules to generate a solvable conflict - for (const ruleId of ['rule-1', 'rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - tags: ['one', 'two', 'four'], - }); - } - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'A', - version: 2, - tags: ['one', 'two', 'FOUR'], - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(3); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); - }); - - it('should show how many rules have updates with non-solvable conflicts', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Customize a scalar array field on the installed rules to generate a solvable conflict - for (const ruleId of ['rule-1', 'rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - tags: ['one', 'two', 'four'], - }); - } - - // Customize a single-line field on two installed rules to generate a non-solvable conflict - for (const ruleId of ['rule-2', 'rule-3']) { - await patchRule(supertest, log, { - rule_id: ruleId, - name: 'B', - }); - } - - const updatedRuleAssetSavedObjects = ['rule-1', 'rule-2', 'rule-3'].map((ruleId) => - createRuleAssetSavedObject({ - rule_id: ruleId, - name: 'C', - version: 2, - tags: ['one', 'two', 'FOUR'], - }) - ); - - await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); - - const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(3); - expect(reviewResponse.stats.num_rules_with_conflicts).toBe(3); - expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(2); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts index 7b90b4821856c..243f130ee937e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts @@ -6,7 +6,7 @@ */ import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; import { nameField } from './name'; import { descriptionField } from './description'; @@ -53,7 +53,6 @@ export default (context: FtrProviderContext): void => { describe('@ess @serverless @skipInServerlessMKI diffable rule fields', () => { beforeEach(async () => { await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); await deleteAllPrebuiltRuleAssets(es, log); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts index 0b70a1536f8fc..f8431c2608953 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts @@ -12,6 +12,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./is_customized_calculation')); loadTestFile(require.resolve('./import_rules')); loadTestFile(require.resolve('./rules_export')); + loadTestFile(require.resolve('./preview_prebuilt_rules_upgrade')); loadTestFile(require.resolve('./upgrade_prebuilt_rules')); loadTestFile(require.resolve('./diffable_rule_fields')); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts new file mode 100644 index 0000000000000..a7566eb8229af --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts @@ -0,0 +1,400 @@ +/* + * 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 expect from 'expect'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { deleteAllPrebuiltRuleAssets, reviewPrebuiltRulesToUpgrade } from '../../../../utils'; +import { setUpRuleUpgrade } from '../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + const deps = { + es, + supertest, + log, + }; + + describe('@ess @serverless @skipInServerlessMKI preview prebuilt rules upgrade', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe('stats', () => { + it('returns num of rules with upgrades', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 2, + }); + }); + + it('returns zero conflicts when there are no conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + }); + + it('returns num of rules with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + + it('returns num of rules with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_non_solvable_conflicts: 1, + }); + }); + + it('returns num of rules with conflicts when historical versions are missing', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + }); + + describe('fields diff stats', () => { + it('returns num of fields with updates', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_updates: 3, // name + tags + version = 3 fields + }); + }); + + it('returns num of fields with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_conflicts: 2, + }); + }); + + it('returns num of fields with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff).toMatchObject({ + num_fields_with_non_solvable_conflicts: 1, + }); + }); + }); + + describe('fields diff', () => { + it('returns fields diff', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.rules[0].diff.fields).toMatchObject({ + name: expect.any(Object), + tags: expect.any(Object), + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts index b74ba80405e72..0e9cbef2e1468 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts @@ -6,7 +6,7 @@ */ import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { deleteAllTimelines, deleteAllPrebuiltRuleAssets } from '../../../../../utils'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; import { bulkUpgradeAllPrebuiltRules } from './bulk_upgrade_all_prebuilt_rules'; import { bulkUpgradeSelectedPrebuiltRules } from './bulk_upgrade_selected_prebuilt_rules'; @@ -20,7 +20,6 @@ export default (context: FtrProviderContext): void => { describe('@ess @serverless @skipInServerlessMKI upgrade prebuilt rules', () => { beforeEach(async () => { await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); await deleteAllPrebuiltRuleAssets(es, log); }); From 98a254ed7493cfb4696b34e4dcbb7e972184d1d3 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 3 Feb 2025 17:30:46 +0100 Subject: [PATCH 10/20] temporally disable saved query integration tests --- .../diffable_rule_fields/index.ts | 4 +- .../kql_query.saved_query.ts | 1428 +++++++++-------- 2 files changed, 717 insertions(+), 715 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts index 243f130ee937e..4f59515409904 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts @@ -32,7 +32,7 @@ import { investigationFieldsField } from './investigation_fields'; import { dataSourceField } from './data_source'; import { alertSuppressionField } from './alert_suppression'; import { inlineQueryKqlQueryField } from './kql_query.inline_query'; -import { savedQueryKqlQueryField } from './kql_query.saved_query'; +// import { savedQueryKqlQueryField } from './kql_query.saved_query'; import { eqlQueryField } from './eql_query'; import { esqlQueryField } from './esql_query'; import { threatIndexField } from './threat_index'; @@ -85,7 +85,7 @@ export default (context: FtrProviderContext): void => { inlineQueryKqlQueryField(context); // Saved Query rule types - savedQueryKqlQueryField(context); + // savedQueryKqlQueryField(context); // EQL rule type eqlQueryField(context); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts index ba04dac707ebe..4cb38ace95ac5 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts @@ -5,716 +5,718 @@ * 2.0. */ -import expect from 'expect'; -import { - KqlQueryType, - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - - describe('"kql_query" with saved query', () => { - describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: {}, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: {}, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id1', - }, - target_version: { - saved_query_id: 'saved_query_id2', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'saved_query_id2', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'saved_query_id2', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id1', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'saved_query_id2', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'saved_query_id2', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id2', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'saved_query_id2', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'saved_query_id2', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id3', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - saved_query_id: 'saved_query_id1', - }, - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id3', - }, - merged_version: { - saved_query_id: 'saved_query_id2', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('without historical versions', () => { - describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - - describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'saved_query', - saved_id: 'saved_query_id1', - }, - patch: { - type: 'saved_query', - saved_id: 'saved_query_id2', - }, - upgrade: { - type: 'saved_query', - saved_id: 'saved_query_id3', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - current_version: { - saved_query_id: 'saved_query_id2', - }, - target_version: { - saved_query_id: 'saved_query_id3', - }, - merged_version: { - saved_query_id: 'saved_query_id3', - }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.saved_query, - saved_query_id: 'resolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - saved_id: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - saved_id: 'resolved', - }); - }); - }); - }); - }); -} +// Temporally comment contents until https://github.com/elastic/kibana/issues/209343 is fixed + +// import expect from 'expect'; +// import { +// KqlQueryType, +// ModeEnum, +// ThreeWayDiffConflict, +// ThreeWayDiffOutcome, +// ThreeWayMergeOutcome, +// } from '@kbn/security-solution-plugin/common/api/detection_engine'; +// import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +// import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +// import { +// DEFAULT_TEST_RULE_ID, +// setUpRuleUpgrade, +// } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + +// export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { +// const es = getService('es'); +// const supertest = getService('supertest'); +// const log = getService('log'); +// const securitySolutionApi = getService('securitySolutionApi'); + +// const deps = { +// es, +// supertest, +// log, +// }; + +// describe('"kql_query" with saved query', () => { +// describe('non-customized w/o an upgrade (AAA diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: {}, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// }, +// deps, +// }); +// }); + +// it('does NOT return upgrade review', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 0, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 1, +// num_fields_with_conflicts: 0, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).not.toMatchObject({ +// kql_query: expect.anything(), +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 0, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('non-customized w/ an upgrade (AAB diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: {}, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// }, +// deps, +// }); +// }); + +// it('returns upgrade review', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 0, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 2, +// num_fields_with_conflicts: 0, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).toMatchObject({ +// kql_query: { +// base_version: { +// saved_query_id: 'saved_query_id1', +// }, +// current_version: { +// saved_query_id: 'saved_query_id1', +// }, +// target_version: { +// saved_query_id: 'saved_query_id2', +// }, +// merged_version: { +// saved_query_id: 'saved_query_id2', +// }, +// diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, +// merge_outcome: ThreeWayMergeOutcome.Target, +// conflict: ThreeWayDiffConflict.NONE, +// has_update: true, +// has_base_version: true, +// }, +// }); +// }); + +// it('upgrades to MERGED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 0, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'MERGED', +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 0, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('customized w/o an upgrade (ABA diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// }, +// deps, +// }); +// }); + +// it('returns upgrade preview', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 0, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 1, +// num_fields_with_conflicts: 0, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).toMatchObject({ +// kql_query: { +// base_version: { +// saved_query_id: 'saved_query_id1', +// }, +// current_version: { +// saved_query_id: 'saved_query_id2', +// }, +// target_version: { +// saved_query_id: 'saved_query_id1', +// }, +// merged_version: { +// saved_query_id: 'saved_query_id2', +// }, +// diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, +// merge_outcome: ThreeWayMergeOutcome.Current, +// conflict: ThreeWayDiffConflict.NONE, +// has_update: false, +// has_base_version: true, +// }, +// }); +// }); + +// it('upgrades to MERGED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'MERGED', +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('customized w/ the matching upgrade (ABB diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// }, +// deps, +// }); +// }); + +// it('returns upgrade preview', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 0, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 1, +// num_fields_with_conflicts: 0, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).toMatchObject({ +// kql_query: { +// base_version: { +// saved_query_id: 'saved_query_id1', +// }, +// current_version: { +// saved_query_id: 'saved_query_id2', +// }, +// target_version: { +// saved_query_id: 'saved_query_id2', +// }, +// merged_version: { +// saved_query_id: 'saved_query_id2', +// }, +// diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, +// merge_outcome: ThreeWayMergeOutcome.Current, +// conflict: ThreeWayDiffConflict.NONE, +// has_update: false, +// has_base_version: true, +// }, +// }); +// }); + +// it('upgrades to MERGED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'MERGED', +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'saved_query_id2', +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id3', +// }, +// }, +// deps, +// }); +// }); + +// it('returns upgrade preview', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 1, +// num_rules_with_non_solvable_conflicts: 1, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 2, +// num_fields_with_conflicts: 1, +// num_fields_with_non_solvable_conflicts: 1, +// }); +// expect(response.rules[0].diff.fields).toMatchObject({ +// kql_query: { +// base_version: { +// saved_query_id: 'saved_query_id1', +// }, +// current_version: { +// saved_query_id: 'saved_query_id2', +// }, +// target_version: { +// saved_query_id: 'saved_query_id3', +// }, +// merged_version: { +// saved_query_id: 'saved_query_id2', +// }, +// diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, +// merge_outcome: ThreeWayMergeOutcome.Current, +// conflict: ThreeWayDiffConflict.NON_SOLVABLE, +// has_update: true, +// has_base_version: true, +// }, +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('without historical versions', () => { +// describe('customized w/ the matching upgrade (-AA diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// }, +// removeInstalledAssets: true, +// deps, +// }); +// }); + +// it('does NOT return upgrade review', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 0, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 1, +// num_fields_with_conflicts: 0, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).not.toMatchObject({ +// kql_query: expect.anything(), +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); + +// describe('customized w/ an upgrade (-AB diff case)', () => { +// beforeEach(async () => { +// await setUpRuleUpgrade({ +// assets: { +// installed: { +// type: 'saved_query', +// saved_id: 'saved_query_id1', +// }, +// patch: { +// type: 'saved_query', +// saved_id: 'saved_query_id2', +// }, +// upgrade: { +// type: 'saved_query', +// saved_id: 'saved_query_id3', +// }, +// }, +// removeInstalledAssets: true, +// deps, +// }); +// }); + +// it('returns upgrade preview', async () => { +// const response = await reviewPrebuiltRulesToUpgrade(supertest); + +// expect(response.rules).toHaveLength(1); +// expect(response.stats).toMatchObject({ +// num_rules_to_upgrade_total: 1, +// num_rules_with_conflicts: 1, +// num_rules_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff).toMatchObject({ +// num_fields_with_updates: 2, +// num_fields_with_conflicts: 1, +// num_fields_with_non_solvable_conflicts: 0, +// }); +// expect(response.rules[0].diff.fields).toMatchObject({ +// kql_query: { +// current_version: { +// saved_query_id: 'saved_query_id2', +// }, +// target_version: { +// saved_query_id: 'saved_query_id3', +// }, +// merged_version: { +// saved_query_id: 'saved_query_id3', +// }, +// diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, +// merge_outcome: ThreeWayMergeOutcome.Target, +// conflict: ThreeWayDiffConflict.SOLVABLE, +// has_update: true, +// has_base_version: false, +// }, +// }); +// }); + +// it('upgrades to RESOLVED value', async () => { +// const response = await performUpgradePrebuiltRules(es, supertest, { +// mode: ModeEnum.SPECIFIC_RULES, +// rules: [ +// { +// rule_id: DEFAULT_TEST_RULE_ID, +// revision: 1, +// version: 2, +// fields: { +// kql_query: { +// pick_version: 'RESOLVED', +// resolved_value: { +// type: KqlQueryType.saved_query, +// saved_query_id: 'resolved', +// }, +// }, +// }, +// }, +// ], +// }); + +// const upgradedRule = await securitySolutionApi.readRule({ +// query: { rule_id: DEFAULT_TEST_RULE_ID }, +// }); + +// expect(response.results.updated[0]).toMatchObject({ +// saved_id: 'resolved', +// }); +// expect(upgradedRule.body).toMatchObject({ +// saved_id: 'resolved', +// }); +// }); +// }); +// }); +// }); +// } From b63ca486c86fddecee6a4b349b6361f1db694631 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 4 Feb 2025 15:50:17 +0100 Subject: [PATCH 11/20] enable threshold rule type for KQL inline query tests --- .../kql_query.inline_query.ts | 148 +++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts index 7173790ab48ec..6266a952a199d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts @@ -20,7 +20,7 @@ import { setUpRuleUpgrade, } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; -const RULE_TYPES = ['query', 'threat_match', /* 'threshold',*/ 'new_terms'] as const; +const RULE_TYPES = ['query', 'threat_match', 'threshold', 'new_terms'] as const; export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): void { const es = getService('es'); @@ -35,7 +35,7 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }; for (const ruleType of RULE_TYPES) { - describe('"kql_query" with inline query', () => { + describe(`"kql_query" with inline query for ${ruleType} rule`, () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { describe('without filters', () => { beforeEach(async () => { @@ -140,6 +140,14 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo installed: { type: ruleType, filters: [FILTER], + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, @@ -152,10 +160,26 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }, }, ], + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, filters: [FILTER], + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, deps, @@ -328,15 +352,39 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, deps, @@ -470,15 +518,39 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, query: '*:*', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, deps, @@ -612,15 +684,39 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, query: 'process.name:*.sys', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, deps, @@ -722,15 +818,39 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, query: 'process.name:*.sys', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, query: 'process.name:*.sys', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, removeInstalledAssets: true, @@ -802,15 +922,39 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo type: ruleType, query: 'process.name:*.exe', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, patch: { type: ruleType, query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, upgrade: { type: ruleType, query: 'process.name:*.sys', language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), }, }, removeInstalledAssets: true, From e55e89fcf94208f3ade2138caf434a8f755c77c6 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 4 Feb 2025 15:50:52 +0100 Subject: [PATCH 12/20] fix data source integration tests --- .../customization_enabled/diffable_rule_fields/data_source.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts index b20ccca3dd4a9..0567a41582fba 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts @@ -719,7 +719,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { num_fields_with_conflicts: 0, num_fields_with_non_solvable_conflicts: 0, }); - expect(response.rules[0].diff.fields).toMatchObject({ + expect(response.rules[0].diff.fields).not.toMatchObject({ data_source: expect.anything(), }); }); @@ -752,7 +752,7 @@ export function dataSourceField({ getService }: FtrProviderContext): void { expect(response.results.updated[0]).toMatchObject({ data_view_id: 'dataViewResolved', }); - expect(upgradedRule.body).not.toMatchObject({ + expect(upgradedRule.body).toMatchObject({ data_view_id: 'dataViewResolved', }); }); From 308540c6fbfafae85089b4c2b784a75663b537de Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 5 Feb 2025 13:11:37 +0100 Subject: [PATCH 13/20] extract diffable rule per field tests into a separate execution group --- .../configs/ess.config.ts | 34 +++++++++++++++++++ .../configs/serverless.config.ts | 21 ++++++++++++ .../customization_enabled/index.ts | 1 - 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts new file mode 100644 index 0000000000000..a8348c192c236 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts @@ -0,0 +1,34 @@ +/* + * 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 { FtrConfigProviderContext } from '@kbn/test'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile( + require.resolve('../../../../../../../../config/ess/config.base.trial') + ); + + const testConfig = { + ...functionalConfig.getAll(), + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Enabled Per Field Integration Tests - ESS Env', + }, + }; + testConfig.kbnTestServer.serverArgs = testConfig.kbnTestServer.serverArgs.map((arg: string) => { + // Override the default value of `--xpack.securitySolution.enableExperimental` to enable the prebuilt rules customization feature + if (arg.includes('--xpack.securitySolution.enableExperimental')) { + return `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'prebuiltRulesCustomizationEnabled', + ])}`; + } + return arg; + }); + + return testConfig; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts new file mode 100644 index 0000000000000..b98031d410bf8 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts @@ -0,0 +1,21 @@ +/* + * 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 { createTestConfig } from '../../../../../../../../config/serverless/config.base'; + +export default createTestConfig({ + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Enabled Per Field Integration Tests - Serverless Env', + }, + kbnTestServerArgs: [ + `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'prebuiltRulesCustomizationEnabled', + ])}`, + ], +}); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts index f8431c2608953..0d811f57288ae 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/index.ts @@ -14,6 +14,5 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./rules_export')); loadTestFile(require.resolve('./preview_prebuilt_rules_upgrade')); loadTestFile(require.resolve('./upgrade_prebuilt_rules')); - loadTestFile(require.resolve('./diffable_rule_fields')); }); }; From 66d2432c41a2695eb372ae83c03229cfdb346014 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Wed, 5 Feb 2025 13:47:36 +0100 Subject: [PATCH 14/20] update FTR lists --- .buildkite/ftr_security_serverless_configs.yml | 1 + .buildkite/ftr_security_stateful_configs.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.buildkite/ftr_security_serverless_configs.yml b/.buildkite/ftr_security_serverless_configs.yml index 57d0c977795fa..e193366097552 100644 --- a/.buildkite/ftr_security_serverless_configs.yml +++ b/.buildkite/ftr_security_serverless_configs.yml @@ -78,6 +78,7 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless_complete_tier.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless_essentials_tier.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/serverless.config.ts diff --git a/.buildkite/ftr_security_stateful_configs.yml b/.buildkite/ftr_security_stateful_configs.yml index 269be53f635bd..a49a9b32b20c2 100644 --- a/.buildkite/ftr_security_stateful_configs.yml +++ b/.buildkite/ftr_security_stateful_configs.yml @@ -59,6 +59,7 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess_basic_license.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess_trial_license.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/ess.config.ts From ffd88d0605a9acb0336a7cfcc0095bcd252aaac0 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 10 Feb 2025 16:45:52 +0100 Subject: [PATCH 15/20] split diffable rule fields tests in groups --- .../ftr_security_serverless_configs.yml | 3 +- .buildkite/ftr_security_stateful_configs.yml | 3 +- .../{ => common_fields}/alert_suppression.ts | 6 +- .../{ => common_fields}/building_block.ts | 6 +- .../{ => common_fields}/configs/ess.config.ts | 2 +- .../configs/serverless.config.ts | 2 +- .../{ => common_fields}/data_source.ts | 6 +- .../{ => common_fields}/description.ts | 6 +- .../{ => common_fields}/false_positives.ts | 6 +- .../{ => common_fields}/index.ts | 50 ++------------ .../investigation_fields.ts | 6 +- .../{ => common_fields}/max_signals.ts | 6 +- .../{ => common_fields}/name.ts | 6 +- .../{ => common_fields}/note.ts | 6 +- .../{ => common_fields}/references.ts | 6 +- .../related_integrations.ts | 6 +- .../{ => common_fields}/required_fields.ts | 6 +- .../{ => common_fields}/risk_score.ts | 6 +- .../{ => common_fields}/risk_score_mapping.ts | 6 +- .../{ => common_fields}/rule_name_override.ts | 6 +- .../{ => common_fields}/rule_schedule.ts | 6 +- .../{ => common_fields}/setup.ts | 6 +- .../{ => common_fields}/severity.ts | 6 +- .../{ => common_fields}/severity_mapping.ts | 6 +- .../{ => common_fields}/tags.ts | 6 +- .../{ => common_fields}/threat.ts | 6 +- .../{ => common_fields}/timeline_template.ts | 6 +- .../{ => common_fields}/timestamp_override.ts | 6 +- .../anomaly_threshold.ts | 6 +- .../configs/ess.config.ts | 34 ++++++++++ .../configs/serverless.config.ts | 21 ++++++ .../{ => type_specific_fields}/eql_query.ts | 6 +- .../{ => type_specific_fields}/esql_query.ts | 6 +- .../history_window_start.ts | 6 +- .../type_specific_fields/index.ts | 65 +++++++++++++++++++ .../kql_query.inline_query.ts | 6 +- .../kql_query.saved_query.ts | 0 .../machine_learning_job_id.ts | 6 +- .../new_terms_fields.ts | 6 +- .../threat_index.ts | 6 +- .../threat_indicator_path.ts | 6 +- .../threat_mapping.ts | 6 +- .../threat_query.ts | 6 +- .../{ => type_specific_fields}/threshold.ts | 6 +- 44 files changed, 235 insertions(+), 155 deletions(-) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/alert_suppression.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/building_block.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/configs/ess.config.ts (93%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/configs/serverless.config.ts (86%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/data_source.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/description.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/false_positives.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/index.ts (58%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/investigation_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/max_signals.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/name.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/note.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/references.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/related_integrations.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/required_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/risk_score.ts (98%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/risk_score_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/rule_name_override.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/rule_schedule.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/setup.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/severity.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/severity_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/tags.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/threat.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/timeline_template.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => common_fields}/timestamp_override.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/anomaly_threshold.ts (99%) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/ess.config.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/eql_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/esql_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/history_window_start.ts (99%) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/index.ts rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/kql_query.inline_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/kql_query.saved_query.ts (100%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/machine_learning_job_id.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/new_terms_fields.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/threat_index.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/threat_indicator_path.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/threat_mapping.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/threat_query.ts (99%) rename x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/{ => type_specific_fields}/threshold.ts (99%) diff --git a/.buildkite/ftr_security_serverless_configs.yml b/.buildkite/ftr_security_serverless_configs.yml index e193366097552..076442fe5132f 100644 --- a/.buildkite/ftr_security_serverless_configs.yml +++ b/.buildkite/ftr_security_serverless_configs.yml @@ -78,7 +78,8 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/serverless.config.ts - - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless_complete_tier.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/serverless_essentials_tier.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/serverless.config.ts diff --git a/.buildkite/ftr_security_stateful_configs.yml b/.buildkite/ftr_security_stateful_configs.yml index a49a9b32b20c2..e6b40e697921d 100644 --- a/.buildkite/ftr_security_stateful_configs.yml +++ b/.buildkite/ftr_security_stateful_configs.yml @@ -59,7 +59,8 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/update_prebuilt_rules_package/trial_license_complete_tier/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/configs/ess.config.ts - - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess_basic_license.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_disabled/configs/ess_trial_license.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/ess.config.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts index d291c1c83fdf8..53f150a114d15 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/alert_suppression.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function alertSuppressionField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts index 4f4add7850235..a2865e9f05854 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/building_block.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function buildingBlockField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/ess.config.ts similarity index 93% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/ess.config.ts index a8348c192c236..944699b362cfe 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/ess.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/ess.config.ts @@ -9,7 +9,7 @@ import { FtrConfigProviderContext } from '@kbn/test'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const functionalConfig = await readConfigFile( - require.resolve('../../../../../../../../config/ess/config.base.trial') + require.resolve('../../../../../../../../../config/ess/config.base.trial') ); const testConfig = { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/serverless.config.ts similarity index 86% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/serverless.config.ts index b98031d410bf8..5fb299b71e58d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/configs/serverless.config.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/configs/serverless.config.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createTestConfig } from '../../../../../../../../config/serverless/config.base'; +import { createTestConfig } from '../../../../../../../../../config/serverless/config.base'; export default createTestConfig({ testFiles: [require.resolve('..')], diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts index 0567a41582fba..8e2130d74b91d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/data_source.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts @@ -13,12 +13,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function dataSourceField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts index 704fde10fe775..b4ba3fcb170e7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/description.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function descriptionField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts index 2b86af0f414b2..9ec4818bbdea9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/false_positives.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function falsePositivesField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/index.ts similarity index 58% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/index.ts index 4f59515409904..3e99193009a62 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/index.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; -import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../../utils'; +import { deleteAllRules } from '../../../../../../../../../common/utils/security_solution'; import { nameField } from './name'; import { descriptionField } from './description'; import { tagsField } from './tags'; @@ -31,26 +31,13 @@ import { buildingBlockField } from './building_block'; import { investigationFieldsField } from './investigation_fields'; import { dataSourceField } from './data_source'; import { alertSuppressionField } from './alert_suppression'; -import { inlineQueryKqlQueryField } from './kql_query.inline_query'; -// import { savedQueryKqlQueryField } from './kql_query.saved_query'; -import { eqlQueryField } from './eql_query'; -import { esqlQueryField } from './esql_query'; -import { threatIndexField } from './threat_index'; -import { threatQueryField } from './threat_query'; -import { threatMappingField } from './threat_mapping'; -import { threatIndicatorPathField } from './threat_indicator_path'; -import { thresholdField } from './threshold'; -import { machineLearningJobIdField } from './machine_learning_job_id'; -import { anomalyThresholdField } from './anomaly_threshold'; -import { newTermsFieldsField } from './new_terms_fields'; -import { historyWindowStartField } from './history_window_start'; export default (context: FtrProviderContext): void => { const es = context.getService('es'); const supertest = context.getService('supertest'); const log = context.getService('log'); - describe('@ess @serverless @skipInServerlessMKI diffable rule fields', () => { + describe('@ess @serverless @skipInServerlessMKI common diffable rule fields', () => { beforeEach(async () => { await deleteAllRules(supertest, log); await deleteAllPrebuiltRuleAssets(es, log); @@ -80,34 +67,5 @@ export default (context: FtrProviderContext): void => { investigationFieldsField(context); dataSourceField(context); alertSuppressionField(context); - - // Custom Query, Threat Match, Threshold, New Terms rule types - inlineQueryKqlQueryField(context); - - // Saved Query rule types - // savedQueryKqlQueryField(context); - - // EQL rule type - eqlQueryField(context); - - // ES|QL rule type - esqlQueryField(context); - - // Threat Match rule type - threatIndexField(context); - threatQueryField(context); - threatMappingField(context); - threatIndicatorPathField(context); - - // Threshold rule type - thresholdField(context); - - // Machine Learning rule type - machineLearningJobIdField(context); - anomalyThresholdField(context); - - // New Terms rule type - newTermsFieldsField(context); - historyWindowStartField(context); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts index 619b3e0a95b95..a9c298c8c84d1 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/investigation_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function investigationFieldsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts index f8b29097301c3..d20ae762a693b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/max_signals.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function maxSignalsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts index 021079e664e19..e9c3b0b0259d9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/name.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function nameField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts index 0011a0b17254c..e9c0a29c4822c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/note.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function noteField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts index 6e1f8541b1d2d..50840e77f8f09 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/references.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function referencesField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts index 07414773dd933..4f5834b134242 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/related_integrations.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function relatedIntegrationsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts index 80ca5355958d6..c8719f744a2d6 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/required_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function requiredFieldsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts similarity index 98% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts index d1c9974b3376f..4a213ac440851 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function riskScoreField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts index 877c73fd43ee7..2941098adf049 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/risk_score_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function riskScoreMappingField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts index c8b5823bc1304..6cb1b4dac8d1c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_name_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function ruleNameOverrideField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts index 1f3f24260b9e9..b6be69d397ee3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/rule_schedule.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function ruleScheduleField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts index 71b23250df93f..0249148c6d5df 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/setup.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function setupField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts index beafb919c2e14..1cfe4b5310d02 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function severityField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts index eb3c32744d6c9..8cc8eefb21b2f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/severity_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function severityMappingField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts index 8112c1d02f229..b74d6c361b6ce 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/tags.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function tagsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts index e1a2141164c12..3fddab56ad929 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function threatField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts index de50f64d45f12..783a38446538b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timeline_template.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function timelineTemplateField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts index e178c3a323af6..fb89b5eef68ff 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/timestamp_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function timestampOverrideField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts index 5884c1ad87f37..5093191d81a7a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/anomaly_threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function anomalyThresholdField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/ess.config.ts new file mode 100644 index 0000000000000..944699b362cfe --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/ess.config.ts @@ -0,0 +1,34 @@ +/* + * 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 { FtrConfigProviderContext } from '@kbn/test'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile( + require.resolve('../../../../../../../../../config/ess/config.base.trial') + ); + + const testConfig = { + ...functionalConfig.getAll(), + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Enabled Per Field Integration Tests - ESS Env', + }, + }; + testConfig.kbnTestServer.serverArgs = testConfig.kbnTestServer.serverArgs.map((arg: string) => { + // Override the default value of `--xpack.securitySolution.enableExperimental` to enable the prebuilt rules customization feature + if (arg.includes('--xpack.securitySolution.enableExperimental')) { + return `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'prebuiltRulesCustomizationEnabled', + ])}`; + } + return arg; + }); + + return testConfig; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts new file mode 100644 index 0000000000000..5fb299b71e58d --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts @@ -0,0 +1,21 @@ +/* + * 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 { createTestConfig } from '../../../../../../../../../config/serverless/config.base'; + +export default createTestConfig({ + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Rules Management - Prebuilt Rule Customization Enabled Per Field Integration Tests - Serverless Env', + }, + kbnTestServerArgs: [ + `--xpack.securitySolution.enableExperimental=${JSON.stringify([ + 'prebuiltRulesCustomizationEnabled', + ])}`, + ], +}); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts index 04d538ad61c8a..9f82f3ace5e85 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/eql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function eqlQueryField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts index 6d1ee7a2dcdc0..674ce62a13d24 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/esql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function esqlQueryField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts index 53d218cf2caf7..27ef929aaab79 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/history_window_start.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function historyWindowStartField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/index.ts new file mode 100644 index 0000000000000..3412a151b14a7 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/index.ts @@ -0,0 +1,65 @@ +/* + * 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 { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { deleteAllPrebuiltRuleAssets } from '../../../../../../utils'; +import { deleteAllRules } from '../../../../../../../../../common/utils/security_solution'; +import { inlineQueryKqlQueryField } from './kql_query.inline_query'; +// import { savedQueryKqlQueryField } from './kql_query.saved_query'; +import { eqlQueryField } from './eql_query'; +import { esqlQueryField } from './esql_query'; +import { threatIndexField } from './threat_index'; +import { threatQueryField } from './threat_query'; +import { threatMappingField } from './threat_mapping'; +import { threatIndicatorPathField } from './threat_indicator_path'; +import { thresholdField } from './threshold'; +import { machineLearningJobIdField } from './machine_learning_job_id'; +import { anomalyThresholdField } from './anomaly_threshold'; +import { newTermsFieldsField } from './new_terms_fields'; +import { historyWindowStartField } from './history_window_start'; + +export default (context: FtrProviderContext): void => { + const es = context.getService('es'); + const supertest = context.getService('supertest'); + const log = context.getService('log'); + + describe('@ess @serverless @skipInServerlessMKI type specific diffable rule fields', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + // Custom Query, Threat Match, Threshold, New Terms rule types + inlineQueryKqlQueryField(context); + + // Saved Query rule types + // savedQueryKqlQueryField(context); + + // EQL rule type + eqlQueryField(context); + + // ES|QL rule type + esqlQueryField(context); + + // Threat Match rule type + threatIndexField(context); + threatQueryField(context); + threatMappingField(context); + threatIndicatorPathField(context); + + // Threshold rule type + thresholdField(context); + + // Machine Learning rule type + machineLearningJobIdField(context); + anomalyThresholdField(context); + + // New Terms rule type + newTermsFieldsField(context); + historyWindowStartField(context); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts index 6266a952a199d..b434728d74def 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.inline_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts @@ -13,12 +13,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; const RULE_TYPES = ['query', 'threat_match', 'threshold', 'new_terms'] as const; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/kql_query.saved_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts index a3747630c4ca5..0913c372057d4 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/machine_learning_job_id.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function machineLearningJobIdField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts index cd03ca3c7bd9a..612b6d1e0e785 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/new_terms_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function newTermsFieldsField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts index c89edc4cb75a7..d892b0ec40703 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function threatIndexField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts index 44a0d07c898a9..eef80c734dc3c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_indicator_path.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function threatIndicatorPathField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts index 49171debe25a3..44670bd9f7acf 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function threatMappingField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts index a9ffe53e52dd1..1e2957860d22f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threat_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts @@ -13,12 +13,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function threatQueryField({ getService }: FtrProviderContext): void { const es = getService('es'); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts similarity index 99% rename from x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts index acbd074a23675..37d54b7aeed2a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts @@ -12,12 +12,12 @@ import { ThreeWayDiffOutcome, ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; import { DEFAULT_TEST_RULE_ID, setUpRuleUpgrade, -} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export function thresholdField({ getService }: FtrProviderContext): void { const es = getService('es'); From 45dc574c5f86dd6cd4516149594170a2c04a42eb Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 10 Feb 2025 17:57:41 +0100 Subject: [PATCH 16/20] throw on ES bulk API failures --- .../prebuilt_rules/create_prebuilt_rule_saved_objects.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts index 9a8897891d812..8780bf2b49353 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts @@ -115,7 +115,7 @@ export const createHistoricalPrebuiltRuleAssetSavedObjects = async ( es: Client, rules = SAMPLE_PREBUILT_RULES_WITH_HISTORICAL_VERSIONS ): Promise => { - await es.bulk({ + const response = await es.bulk({ refresh: true, body: rules.flatMap((doc) => [ { @@ -127,4 +127,10 @@ export const createHistoricalPrebuiltRuleAssetSavedObjects = async ( doc, ]), }); + + if (response.errors) { + throw new Error( + `Unable to bulk create rule assets. Response items: ${JSON.stringify(response.items)}` + ); + } }; From 9f8572e244389626f820b33880c773590e3f19f3 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 13 Feb 2025 16:49:41 +0100 Subject: [PATCH 17/20] refactor diffable rule upgrade tests --- .../common_fields/alert_suppression.ts | 892 +++----- .../common_fields/building_block.ts | 885 +++----- .../common_fields/data_source.ts | 1822 ++++++----------- .../common_fields/description.ts | 901 +++----- .../common_fields/false_positives.ts | 892 +++----- .../common_fields/investigation_fields.ts | 892 +++----- .../common_fields/max_signals.ts | 892 +++----- .../common_fields/name.ts | 892 +++----- .../common_fields/note.ts | 892 +++----- .../common_fields/references.ts | 892 +++----- .../common_fields/related_integrations.ts | 1182 ++++------- .../common_fields/required_fields.ts | 1170 ++++------- .../common_fields/risk_score.ts | 892 +++----- .../common_fields/risk_score_mapping.ts | 1270 ++++-------- .../common_fields/rule_name_override.ts | 892 +++----- .../common_fields/rule_schedule.ts | 1017 +++------ .../common_fields/setup.ts | 892 +++----- .../common_fields/severity.ts | 894 +++----- .../common_fields/severity_mapping.ts | 1272 ++++-------- .../common_fields/tags.ts | 892 +++----- .../common_fields/threat.ts | 1336 +++++------- .../common_fields/timeline_template.ts | 955 +++------ .../common_fields/timestamp_override.ts | 892 +++----- .../diffable_rule_fields/test_helpers.ts | 546 +++++ .../type_specific_fields/anomaly_threshold.ts | 902 +++----- .../type_specific_fields/eql_query.ts | 1014 ++++----- .../type_specific_fields/esql_query.ts | 942 +++------ .../history_window_start.ts | 902 +++----- .../kql_query.inline_query.ts | 1374 +++++-------- .../kql_query.saved_query.ts | 1094 ++++------ .../machine_learning_job_id.ts | 904 +++----- .../type_specific_fields/new_terms_fields.ts | 902 +++----- .../type_specific_fields/threat_index.ts | 902 +++----- .../threat_indicator_path.ts | 902 +++----- .../type_specific_fields/threat_mapping.ts | 1004 +++------ .../type_specific_fields/threat_query.ts | 995 +++------ .../type_specific_fields/threshold.ts | 904 +++----- .../preview_prebuilt_rules_upgrade.ts | 2 + .../review_upgrade_prebuilt_rules.ts | 9 + .../prebuilt_rules/set_up_rule_upgrade.ts | 8 +- 40 files changed, 12304 insertions(+), 24410 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/test_helpers.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts index 53f150a114d15..9b6fad04aeb71 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/alert_suppression.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function alertSuppressionField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"alert_suppression"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - alert_suppression: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldC'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldC'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldC'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldC'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldC'] } }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldA'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - alert_suppression: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', alert_suppression: { group_by: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { group_by: ['fieldA'] }, + current: { group_by: ['fieldA'] }, + target: { group_by: ['fieldB'] }, + merged: { group_by: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldA'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { alert_suppression: { group_by: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { group_by: ['fieldA'] }, + current: { group_by: ['fieldB'] }, + target: { group_by: ['fieldA'] }, + merged: { group_by: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldB'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { alert_suppression: { group_by: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', alert_suppression: { group_by: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { group_by: ['fieldA'] }, + current: { group_by: ['fieldB'] }, + target: { group_by: ['fieldB'] }, + merged: { group_by: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldC'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - base_version: { group_by: ['fieldA'] }, - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldC'] }, - merged_version: { group_by: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { group_by: ['fieldA'] }, + current: { group_by: ['fieldB'] }, + target: { group_by: ['fieldC'] }, + merged: { group_by: ['fieldB'] }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldB'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - alert_suppression: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldB'] }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - alert_suppression: { group_by: ['fieldA'] }, - }, - patch: { - alert_suppression: { group_by: ['fieldB'] }, - }, - upgrade: { - type: 'query', - alert_suppression: { group_by: ['fieldC'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - alert_suppression: { - current_version: { group_by: ['fieldB'] }, - target_version: { group_by: ['fieldC'] }, - merged_version: { group_by: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + }, + patch: { + alert_suppression: { group_by: ['fieldB'] }, + }, + upgrade: { + type: 'query', + alert_suppression: { group_by: ['fieldC'] }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { group_by: ['fieldB'] }, + target: { group_by: ['fieldC'] }, + merged: { group_by: ['fieldC'] }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - alert_suppression: { - pick_version: 'RESOLVED', - resolved_value: { group_by: ['fieldD'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - expect(upgradedRule.body).toMatchObject({ - alert_suppression: { group_by: ['fieldD'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'alert_suppression', + resolvedValue: { group_by: ['fieldD'] }, + expectedFieldsAfterUpgrade: { alert_suppression: { group_by: ['fieldD'] } }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts index a2865e9f05854..a86153371dc28 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/building_block.ts @@ -5,643 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function buildingBlockField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"building_block"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: {}, - upgrade: { - type: 'query', - building_block_type: 'default', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - building_block: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: undefined, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).not.toMatchObject({ - building_block_type: expect.anything(), - }); - expect(upgradedRule.body).not.toMatchObject({ - building_block_type: expect.anything(), - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: undefined, + expectedFieldsAfterUpgrade: { building_block_type: undefined }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: {}, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: {}, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { type: 'default' }, + current: { type: 'default' }, + target: undefined, + merged: undefined, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - building_block: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).not.toMatchObject({ - building_block_type: expect.anything(), - }); - expect(upgradedRule.body).not.toMatchObject({ - building_block_type: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedFieldsAfterUpgrade: { building_block_type: undefined }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: '', - }, - upgrade: { - type: 'query', - building_block_type: 'default', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - target_version: { type: 'default' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: '', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { building_block_type: '', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + }, + upgrade: { + type: 'query', + building_block_type: 'default', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { type: 'default' }, + current: undefined, + target: { type: 'default' }, + merged: undefined, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedFieldsAfterUpgrade: { building_block_type: '' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: 'custom', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - target_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { building_block_type: 'custom', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', building_block_type: 'custom', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { type: 'default' }, + current: { type: 'custom' }, + target: { type: 'custom' }, + merged: { type: 'custom' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedFieldsAfterUpgrade: { building_block_type: 'custom' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - building_block: { - base_version: { type: 'default' }, - current_version: { type: 'custom' }, - merged_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { type: 'default' }, + current: { type: 'custom' }, + target: undefined, + merged: { type: 'custom' }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: 'custom', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - building_block: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: 'custom', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - building_block_type: 'default', - }, - patch: { - building_block_type: 'custom', - }, - upgrade: { - type: 'query', - building_block_type: undefined, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - building_block: { - current_version: { type: 'custom' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + building_block_type: 'default', + }, + patch: { + building_block_type: 'custom', + }, + upgrade: { + type: 'query', + building_block_type: undefined, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { type: 'custom' }, + target: undefined, + merged: undefined, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - building_block: { - pick_version: 'RESOLVED', - resolved_value: { type: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - building_block_type: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - building_block_type: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'building_block', + resolvedValue: { type: 'resolved' }, + expectedFieldsAfterUpgrade: { building_block_type: 'resolved' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts index 8e2130d74b91d..e2890febe732a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/data_source.ts @@ -5,1327 +5,679 @@ * 2.0. */ -import expect from 'expect'; import { DataSourceType, - ModeEnum, - ThreeWayDiffConflict, ThreeWayDiffOutcome, - ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function dataSourceField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"data_source" with index patterns', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'query', - index: ['indexA'], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'query', - index: ['indexB'], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'query', + index: ['indexB'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + target: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA'], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + merged: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexB'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - merged_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + merged: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA', 'indexC'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: { type: DataSourceType.index_patterns, index_patterns: ['indexA'] }, + current: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target: { type: DataSourceType.index_patterns, index_patterns: ['indexA', 'indexC'], }, - merged_version: { + merged: { type: DataSourceType.index_patterns, index_patterns: ['indexB', 'indexC'], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexB'], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexB'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - index: ['indexA'], - }, - patch: { - index: ['indexB'], - }, - upgrade: { - type: 'query', - index: ['indexA', 'indexC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - current_version: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, - target_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + index: ['indexA'], + }, + patch: { + index: ['indexB'], + }, + upgrade: { + type: 'query', + index: ['indexA', 'indexC'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { type: DataSourceType.index_patterns, index_patterns: ['indexB'] }, + target: { type: DataSourceType.index_patterns, index_patterns: ['indexA', 'indexC'], }, - merged_version: { + merged: { type: DataSourceType.index_patterns, index_patterns: ['indexA', 'indexC'], }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.index_patterns, - index_patterns: ['indexResolved'], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - index: ['indexResolved'], - }); - expect(upgradedRule.body).toMatchObject({ - index: ['indexResolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.index_patterns, + index_patterns: ['indexResolved'], + }, + expectedFieldsAfterUpgrade: { index: ['indexResolved'] }, + }, + getService + ); }); }); }); describe('"data_source" with data view', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: {}, - upgrade: { - type: 'query', - data_view_id: 'dataViewA', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: {}, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: {}, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + target: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewB', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewA', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + merged: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewB', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { data_view_id: 'dataViewB', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', data_view_id: 'dataViewB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + merged: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewC', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, + current: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - base_version: { type: DataSourceType.data_view, data_view_id: 'dataViewA' }, - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewB', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - data_source: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - data_view_id: 'dataViewA', - }, - patch: { - data_view_id: 'dataViewB', - }, - upgrade: { - type: 'query', - data_view_id: 'dataViewC', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - data_source: { - current_version: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, - target_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - merged_version: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + data_view_id: 'dataViewA', + }, + patch: { + data_view_id: 'dataViewB', + }, + upgrade: { + type: 'query', + data_view_id: 'dataViewC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { type: DataSourceType.data_view, data_view_id: 'dataViewB' }, + target: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, + merged: { type: DataSourceType.data_view, data_view_id: 'dataViewC' }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - data_source: { - pick_version: 'RESOLVED', - resolved_value: { - type: DataSourceType.data_view, - data_view_id: 'dataViewResolved', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - expect(upgradedRule.body).toMatchObject({ - data_view_id: 'dataViewResolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'data_source', + resolvedValue: { + type: DataSourceType.data_view, + data_view_id: 'dataViewResolved', + }, + expectedFieldsAfterUpgrade: { data_view_id: 'dataViewResolved' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts index b4ba3fcb170e7..3f06b6e6e8bbd 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/description.ts @@ -5,658 +5,327 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function descriptionField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"description"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: {}, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - description: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: {}, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 3', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: {}, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'Original description line 1\nOriginal description line 2', + current: 'Original description line 1\nOriginal description line 2', + target: 'Original description line 1\nOriginal description line 3', + merged: 'Original description line 1\nOriginal description line 3', }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: 'Original description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 3', - merged_version: 'Original description line 1\nOriginal description line 3', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedFieldsAfterUpgrade: { + description: 'Original description line 1\nOriginal description line 3', }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - description: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Original description line 1\nOriginal description line 3', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Original description line 1\nOriginal description line 3', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: { - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'Original description line 1\nOriginal description line 2', + current: 'Customized description\nOriginal description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 2', - merged_version: + target: 'Original description line 1\nOriginal description line 2', + merged: 'Customized description\nOriginal description line 1\nOriginal description line 2', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }); - expect(upgradedRule.body).toMatchObject({ - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedFieldsAfterUpgrade: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Updated description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description', - current_version: 'Updated description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { description: 'Updated description', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', description: 'Updated description', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'Original description', + current: 'Updated description', + target: 'Updated description', + merged: 'Updated description', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedFieldsAfterUpgrade: { description: 'Updated description' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description line 1\nOriginal description line 2', - }, - patch: { - description: - 'Customized description\nOriginal description line 1\nOriginal description line 2', - }, - upgrade: { - type: 'query', - description: 'Original description line 1\nOriginal description line 3', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - description: { - base_version: 'Original description line 1\nOriginal description line 2', - current_version: + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description line 1\nOriginal description line 2', + }, + patch: { + description: + 'Customized description\nOriginal description line 1\nOriginal description line 2', + }, + upgrade: { + type: 'query', + description: 'Original description line 1\nOriginal description line 3', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: 'Original description line 1\nOriginal description line 2', + current: 'Customized description\nOriginal description line 1\nOriginal description line 2', - target_version: 'Original description line 1\nOriginal description line 3', - merged_version: + target: 'Original description line 1\nOriginal description line 3', + merged: 'Customized description\nOriginal description line 1\nOriginal description line 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Updated description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - description: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Updated description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - description: 'Original description', - }, - patch: { - description: 'Customized description', - }, - upgrade: { - type: 'query', - description: 'Updated description', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - description: { - current_version: 'Customized description', - target_version: 'Updated description', - merged_version: 'Updated description', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + description: 'Original description', + }, + patch: { + description: 'Customized description', + }, + upgrade: { + type: 'query', + description: 'Updated description', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'Customized description', + target: 'Updated description', + merged: 'Updated description', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - description: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved description', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - description: 'Resolved description', - }); - expect(upgradedRule.body).toMatchObject({ - description: 'Resolved description', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'description', + resolvedValue: 'Resolved description', + expectedFieldsAfterUpgrade: { description: 'Resolved description' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts index 9ec4818bbdea9..74ff45fae6b3e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/false_positives.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function falsePositivesField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"false_positives"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: {}, - upgrade: { - type: 'query', - false_positives: ['example1'], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - false_positives: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: {}, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example1'], - target_version: ['example2'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - false_positives: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['example2'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: {}, + upgrade: { + type: 'query', false_positives: ['example2'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['example1'], + current: ['example1'], + target: ['example2'], + merged: ['example2'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedFieldsAfterUpgrade: { false_positives: ['example2'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example3'], - }, - upgrade: { - type: 'query', - false_positives: ['example1'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example3'], - target_version: ['example1'], - merged_version: ['example3'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['example3'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { false_positives: ['example3'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + }, + upgrade: { + type: 'query', + false_positives: ['example1'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['example1'], + current: ['example3'], + target: ['example1'], + merged: ['example3'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedFieldsAfterUpgrade: { false_positives: ['example3'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example2'], - target_version: ['example2'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { false_positives: ['example2'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', false_positives: ['example2'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['example1'], + current: ['example2'], + target: ['example2'], + merged: ['example2'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedFieldsAfterUpgrade: { false_positives: ['example2'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example3'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - false_positives: { - base_version: ['example1'], - current_version: ['example2'], - target_version: ['example3'], - merged_version: ['example2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: ['example1'], + current: ['example2'], + target: ['example3'], + merged: ['example2'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - false_positives: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example2'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - false_positives: ['example1'], - }, - patch: { - false_positives: ['example2'], - }, - upgrade: { - type: 'query', - false_positives: ['example3'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - false_positives: { - current_version: ['example2'], - target_version: ['example3'], - merged_version: ['example3'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + false_positives: ['example1'], + }, + patch: { + false_positives: ['example2'], + }, + upgrade: { + type: 'query', + false_positives: ['example3'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['example2'], + target: ['example3'], + merged: ['example3'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - false_positives: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - false_positives: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - false_positives: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'false_positives', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { false_positives: ['resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts index a9c298c8c84d1..afed997049eb6 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/investigation_fields.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function investigationFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"investigation_fields"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - investigation_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: {}, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldA'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - investigation_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: {}, + upgrade: { + type: 'query', investigation_fields: { field_names: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { field_names: ['fieldA'] }, + current: { field_names: ['fieldA'] }, + target: { field_names: ['fieldB'] }, + merged: { field_names: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldA'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { investigation_fields: { field_names: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { field_names: ['fieldA'] }, + current: { field_names: ['fieldB'] }, + target: { field_names: ['fieldA'] }, + merged: { field_names: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldB'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { investigation_fields: { field_names: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', investigation_fields: { field_names: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { field_names: ['fieldA'] }, + current: { field_names: ['fieldB'] }, + target: { field_names: ['fieldB'] }, + merged: { field_names: ['fieldB'] }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldC'] }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - base_version: { field_names: ['fieldA'] }, - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldC'] }, - merged_version: { field_names: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { field_names: ['fieldA'] }, + current: { field_names: ['fieldB'] }, + target: { field_names: ['fieldC'] }, + merged: { field_names: ['fieldB'] }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldB'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - investigation_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldB'] }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - investigation_fields: { field_names: ['fieldA'] }, - }, - patch: { - investigation_fields: { field_names: ['fieldB'] }, - }, - upgrade: { - type: 'query', - investigation_fields: { field_names: ['fieldC'] }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - investigation_fields: { - current_version: { field_names: ['fieldB'] }, - target_version: { field_names: ['fieldC'] }, - merged_version: { field_names: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + investigation_fields: { field_names: ['fieldA'] }, + }, + patch: { + investigation_fields: { field_names: ['fieldB'] }, + }, + upgrade: { + type: 'query', + investigation_fields: { field_names: ['fieldC'] }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { field_names: ['fieldB'] }, + target: { field_names: ['fieldC'] }, + merged: { field_names: ['fieldC'] }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - investigation_fields: { - pick_version: 'RESOLVED', - resolved_value: { field_names: ['resolved'] }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - investigation_fields: { field_names: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'investigation_fields', + resolvedValue: { field_names: ['resolved'] }, + expectedFieldsAfterUpgrade: { investigation_fields: { field_names: ['resolved'] } }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts index d20ae762a693b..122b00022b47e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/max_signals.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function maxSignalsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"max_signals"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: {}, - upgrade: { - type: 'query', - max_signals: 100, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - max_signals: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', + max_signals: 100, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: {}, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 100, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - max_signals: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 150, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: {}, + upgrade: { + type: 'query', max_signals: 150, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 100, + current: 100, + target: 150, + merged: 150, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedFieldsAfterUpgrade: { max_signals: 150 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 100, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 100, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 130, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { max_signals: 130, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + }, + upgrade: { + type: 'query', + max_signals: 100, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 100, + current: 130, + target: 100, + merged: 130, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedFieldsAfterUpgrade: { max_signals: 130 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 130, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 130, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { max_signals: 130, - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', max_signals: 130, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 100, + current: 130, + target: 130, + merged: 130, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedFieldsAfterUpgrade: { max_signals: 130 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - max_signals: { - base_version: 100, - current_version: 130, - target_version: 150, - merged_version: 130, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 100, + current: 130, + target: 150, + merged: 130, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 130, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - max_signals: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 130, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - max_signals: 100, - }, - patch: { - max_signals: 130, - }, - upgrade: { - type: 'query', - max_signals: 150, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - max_signals: { - current_version: 130, - target_version: 150, - merged_version: 150, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + max_signals: 100, + }, + patch: { + max_signals: 130, + }, + upgrade: { + type: 'query', + max_signals: 150, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 130, + target: 150, + merged: 150, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - max_signals: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - max_signals: 50, - }); - expect(upgradedRule.body).toMatchObject({ - max_signals: 50, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'max_signals', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { max_signals: 50 }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts index e9c3b0b0259d9..1030d8f774784 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/name.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function nameField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"name"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: {}, - upgrade: { - type: 'query', - name: 'Original name', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - name: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', + name: 'Original name', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: {}, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Original name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - name: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Updated name', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: {}, + upgrade: { + type: 'query', name: 'Updated name', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'Original name', + current: 'Original name', + target: 'Updated name', + merged: 'Updated name', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedFieldsAfterUpgrade: { name: 'Updated name' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Original name', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Original name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Customized name', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { name: 'Customized name', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + }, + upgrade: { + type: 'query', + name: 'Original name', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'Original name', + current: 'Customized name', + target: 'Original name', + merged: 'Customized name', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedFieldsAfterUpgrade: { name: 'Customized name' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Updated name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Updated name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { name: 'Updated name', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', name: 'Updated name', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'Original name', + current: 'Updated name', + target: 'Updated name', + merged: 'Updated name', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedFieldsAfterUpgrade: { name: 'Updated name' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - name: { - base_version: 'Original name', - current_version: 'Customized name', - target_version: 'Updated name', - merged_version: 'Customized name', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 'Original name', + current: 'Customized name', + target: 'Updated name', + merged: 'Customized name', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Updated name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - name: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Updated name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Original name', - }, - patch: { - name: 'Customized name', - }, - upgrade: { - type: 'query', - name: 'Updated name', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - name: { - current_version: 'Customized name', - target_version: 'Updated name', - merged_version: 'Updated name', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + name: 'Original name', + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'query', + name: 'Updated name', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'Customized name', + target: 'Updated name', + merged: 'Updated name', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - name: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved name', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - name: 'Resolved name', - }); - expect(upgradedRule.body).toMatchObject({ - name: 'Resolved name', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'name', + resolvedValue: 'Resolved name', + expectedFieldsAfterUpgrade: { name: 'Resolved name' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts index e9c0a29c4822c..5b7f1df6834b0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/note.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function noteField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"note"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: {}, - upgrade: { - type: 'query', - note: 'some note', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - note: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', + note: 'some note', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: {}, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'some note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - note: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'updated note', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: {}, + upgrade: { + type: 'query', note: 'updated note', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'some note', + current: 'some note', + target: 'updated note', + merged: 'updated note', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedFieldsAfterUpgrade: { note: 'updated note' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'some note', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'customized note', - target_version: 'some note', - merged_version: 'customized note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'customized note', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: { note: 'customized note', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + }, + upgrade: { + type: 'query', + note: 'some note', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'some note', + current: 'customized note', + target: 'some note', + merged: 'customized note', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedFieldsAfterUpgrade: { note: 'customized note' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'some note', - current_version: 'updated note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: { note: 'updated note', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', note: 'updated note', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'some note', + current: 'updated note', + target: 'updated note', + merged: 'updated note', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedFieldsAfterUpgrade: { note: 'updated note' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'line 1\nline 2', - }, - patch: { - note: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - note: 'line 1\nline 3', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'line 1\nline 2', + }, + patch: { + note: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + note: 'line 1\nline 3', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: 'line 1\nline 2', + current: 'Customized line\nline 1\nline 2', + target: 'line 1\nline 3', + merged: 'Customized line\nline 1\nline 3', }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - note: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'updated note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - note: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'updated note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - note: 'some note', - }, - patch: { - note: 'customized note', - }, - upgrade: { - type: 'query', - note: 'updated note', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - note: { - current_version: 'customized note', - target_version: 'updated note', - merged_version: 'updated note', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + note: 'some note', + }, + patch: { + note: 'customized note', + }, + upgrade: { + type: 'query', + note: 'updated note', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'customized note', + target: 'updated note', + merged: 'updated note', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - note: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved note', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - note: 'Resolved note', - }); - expect(upgradedRule.body).toMatchObject({ - note: 'Resolved note', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'note', + resolvedValue: 'Resolved note', + expectedFieldsAfterUpgrade: { note: 'Resolved note' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts index 50840e77f8f09..cd778ad7a4e40 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/references.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function referencesField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"references"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: {}, - upgrade: { - type: 'query', - references: ['http://url-1'], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - references: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: {}, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - references: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['http://url-1', 'http://url-2'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: {}, + upgrade: { + type: 'query', references: ['http://url-1', 'http://url-2'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['http://url-1'], + current: ['http://url-1'], + target: ['http://url-1', 'http://url-2'], + merged: ['http://url-1', 'http://url-2'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedFieldsAfterUpgrade: { references: ['http://url-1', 'http://url-2'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-2'], - target_version: ['http://url-1'], - merged_version: ['http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['http://url-2'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { references: ['http://url-2'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + }, + upgrade: { + type: 'query', + references: ['http://url-1'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['http://url-1'], + current: ['http://url-2'], + target: ['http://url-1'], + merged: ['http://url-2'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedFieldsAfterUpgrade: { references: ['http://url-2'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-1', 'http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-1', 'http://url-2'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { references: ['http://url-1', 'http://url-2'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', references: ['http://url-1', 'http://url-2'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['http://url-1'], + current: ['http://url-1', 'http://url-2'], + target: ['http://url-1', 'http://url-2'], + merged: ['http://url-1', 'http://url-2'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedFieldsAfterUpgrade: { references: ['http://url-1', 'http://url-2'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-3'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - references: { - base_version: ['http://url-1'], - current_version: ['http://url-2'], - target_version: ['http://url-1', 'http://url-3'], - merged_version: ['http://url-2', 'http://url-3'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-3'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: ['http://url-1'], + current: ['http://url-2'], + target: ['http://url-1', 'http://url-3'], + merged: ['http://url-2', 'http://url-3'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-2'], - }, - upgrade: { - type: 'query', - references: ['http://url-2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - references: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-2'], + }, + upgrade: { + type: 'query', + references: ['http://url-2'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - references: ['http://url-1'], - }, - patch: { - references: ['http://url-3'], - }, - upgrade: { - type: 'query', - references: ['http://url-1', 'http://url-2'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - references: { - current_version: ['http://url-3'], - target_version: ['http://url-1', 'http://url-2'], - merged_version: ['http://url-1', 'http://url-2'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + references: ['http://url-1'], + }, + patch: { + references: ['http://url-3'], + }, + upgrade: { + type: 'query', + references: ['http://url-1', 'http://url-2'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['http://url-3'], + target: ['http://url-1', 'http://url-2'], + merged: ['http://url-1', 'http://url-2'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - references: { - pick_version: 'RESOLVED', - resolved_value: ['https://resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - references: ['https://resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - references: ['https://resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'references', + resolvedValue: ['https://resolved'], + expectedFieldsAfterUpgrade: { references: ['https://resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts index 4f5834b134242..bdc4f0081c31e 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/related_integrations.ts @@ -5,185 +5,118 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function relatedIntegrationsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"related_integrations"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - related_integrations: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + related_integrations: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, + package: 'packageA', + version: '^1.0.0', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: {}, + upgrade: { + type: 'query', related_integrations: [ { - package: 'resolvedPackage', + package: 'packageA', version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ - related_integrations: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ { package: 'resolvedPackage', version: '^1.0.0', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', }, - patch: {}, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], + ], + }, + patch: {}, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [ { package: 'packageA', version: '^1.0.0', }, ], - current_version: [ + current: [ { package: 'packageA', version: '^1.0.0', }, ], - target_version: [ + target: [ { package: 'packageA', version: '^2.0.0', @@ -193,7 +126,7 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo version: '^2.0.0', }, ], - merged_version: [ + merged: [ { package: 'packageA', version: '^2.0.0', @@ -203,511 +136,316 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo version: '^2.0.0', }, ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - related_integrations: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ + { + package: 'resolvedPackage', + version: '^1.0.0', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', related_integrations: [ { package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', + version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, { package: 'packageB', - version: '^2.0.0', - }, - ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^2.0.0', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - related_integrations: [ - { - package: 'resolvedPackage', - version: '^2.0.0', + version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', related_integrations: [ { - package: 'resolvedPackage', - version: '^2.0.0', + package: 'packageA', + version: '^1.0.0', }, ], - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [ { package: 'packageA', version: '^1.0.0', }, ], - current_version: [ + current: [ { package: 'packageB', version: '^1.0.0', }, ], - target_version: [ + target: [ { package: 'packageA', version: '^1.0.0', }, ], - merged_version: [ + merged: [ { package: 'packageB', version: '^1.0.0', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - related_integrations: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ { - package: 'packageB', + package: 'resolvedPackage', version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', related_integrations: [ { - package: 'packageB', + package: 'packageA', version: '^1.0.0', }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { related_integrations: [ { - package: 'resolvedPackage', + package: 'packageB', version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', related_integrations: [ { - package: 'resolvedPackage', + package: 'packageB', version: '^1.0.0', }, ], - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [ { package: 'packageA', version: '^1.0.0', }, ], - current_version: [ + current: [ { package: 'packageB', version: '^1.0.0', }, ], - target_version: [ + target: [ { package: 'packageB', version: '^1.0.0', }, ], - merged_version: [ + merged: [ { package: 'packageB', version: '^1.0.0', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ + { + package: 'resolvedPackage', + version: '^1.0.0', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', related_integrations: [ { - package: 'packageB', + package: 'packageA', version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { related_integrations: [ { package: 'packageB', version: '^1.0.0', }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + upgrade: { + type: 'query', related_integrations: [ { - package: 'resolvedPackage', - version: '^1.0.0', + package: 'packageA', + version: '^2.0.0', }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - related_integrations: [ { - package: 'resolvedPackage', - version: '^1.0.0', + package: 'packageB', + version: '^2.0.0', }, ], - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - related_integrations: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [ { package: 'packageA', version: '^1.0.0', }, ], - current_version: [ + current: [ { package: 'packageB', version: '^1.0.0', }, ], - target_version: [ + target: [ { package: 'packageA', version: '^2.0.0', @@ -717,231 +455,152 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo version: '^2.0.0', }, ], - merged_version: [ + merged: [ { package: 'packageB', version: '^1.0.0', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - related_integrations: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - related_integrations: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ { package: 'resolvedPackage', version: '^1.0.0', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - related_integrations: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { related_integrations: [ { - package: 'resolvedPackage', + package: 'packageB', version: '^1.0.0', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ { package: 'resolvedPackage', version: '^1.0.0', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^1.0.0', - }, - ], - }, - patch: { - related_integrations: [ - { - package: 'packageB', - version: '^1.0.0', - }, - ], - }, - upgrade: { - type: 'query', - related_integrations: [ - { - package: 'packageA', - version: '^2.0.0', - }, - { - package: 'packageB', - version: '^2.0.0', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^1.0.0', }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - related_integrations: { - current_version: [ + ], + }, + patch: { + related_integrations: [ + { + package: 'packageB', + version: '^1.0.0', + }, + ], + }, + upgrade: { + type: 'query', + related_integrations: [ + { + package: 'packageA', + version: '^2.0.0', + }, + { + package: 'packageB', + version: '^2.0.0', + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [ { package: 'packageB', version: '^1.0.0', }, ], - target_version: [ + target: [ { package: 'packageA', version: '^2.0.0', @@ -951,7 +610,7 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo version: '^2.0.0', }, ], - merged_version: [ + merged: [ { package: 'packageA', version: '^2.0.0', @@ -961,59 +620,32 @@ export function relatedIntegrationsField({ getService }: FtrProviderContext): vo version: '^2.0.0', }, ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - related_integrations: { - pick_version: 'RESOLVED', - resolved_value: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - related_integrations: [ - { - package: 'resolvedPackage', - version: '^1.0.0', - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - related_integrations: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'related_integrations', + resolvedValue: [ { package: 'resolvedPackage', version: '^1.0.0', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + related_integrations: [ + { + package: 'resolvedPackage', + version: '^1.0.0', + }, + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts index c8719f744a2d6..5dbd464bc2435 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/required_fields.ts @@ -5,1026 +5,652 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function requiredFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"required_fields"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - required_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + required_fields: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, + name: 'fieldA', + type: 'string', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: {}, + upgrade: { + type: 'query', required_fields: [ { - name: 'resolved', + name: 'fieldA', type: 'string', - ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ - required_fields: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { name: 'resolved', type: 'string', ecs: false, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', }, - patch: {}, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], + ], + }, + patch: {}, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldB', + type: 'string', }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ + ], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - current_version: [ + current: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - target_version: [ + target: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - merged_version: [ + merged: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - required_fields: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - required_fields: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { - name: 'fieldB', + name: 'resolved', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', required_fields: [ { - name: 'fieldB', + name: 'fieldA', type: 'string', - ecs: false, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { required_fields: [ { - name: 'resolved', + name: 'fieldB', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', required_fields: [ { - name: 'resolved', + name: 'fieldA', type: 'string', - ecs: false, }, ], - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - current_version: [ + current: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - target_version: [ + target: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - merged_version: [ + merged: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - required_fields: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { - name: 'fieldB', + name: 'resolved', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', required_fields: [ { - name: 'fieldB', + name: 'fieldA', type: 'string', - ecs: false, - }, - ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { required_fields: [ { - name: 'resolved', + name: 'fieldB', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', required_fields: [ { - name: 'resolved', + name: 'fieldB', type: 'string', - ecs: false, }, ], - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - current_version: [ + current: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - target_version: [ + target: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - merged_version: [ + merged: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - required_fields: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { - name: 'fieldB', + name: 'resolved', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', required_fields: [ { - name: 'fieldB', + name: 'fieldA', type: 'string', - ecs: false, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { required_fields: [ { - name: 'resolved', + name: 'fieldB', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', required_fields: [ { - name: 'resolved', + name: 'fieldC', type: 'string', - ecs: false, }, ], - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldC', - type: 'string', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - required_fields: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [ { name: 'fieldA', type: 'string', ecs: false, }, ], - current_version: [ + current: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - target_version: [ + target: [ { name: 'fieldC', type: 'string', ecs: false, }, ], - merged_version: [ + merged: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - required_fields: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - required_fields: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { name: 'resolved', type: 'string', ecs: false, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], - }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], - }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldB', - type: 'string', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - required_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + required_fields: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, + name: 'fieldA', + type: 'string', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { required_fields: [ { - name: 'resolved', + name: 'fieldB', type: 'string', ecs: false, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', required_fields: [ + { + name: 'fieldB', + type: 'string', + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { name: 'resolved', type: 'string', ecs: false, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - required_fields: [ - { - name: 'fieldA', - type: 'string', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + required_fields: [ + { + name: 'fieldA', + type: 'string', }, - patch: { - required_fields: [ - { - name: 'fieldB', - type: 'string', - ecs: false, - }, - ], + ], + }, + patch: { + required_fields: [ + { + name: 'fieldB', + type: 'string', + ecs: false, }, - upgrade: { - type: 'query', - required_fields: [ - { - name: 'fieldC', - type: 'string', - }, - ], + ], + }, + upgrade: { + type: 'query', + required_fields: [ + { + name: 'fieldC', + type: 'string', }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - required_fields: { - current_version: [ + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [ { name: 'fieldB', type: 'string', ecs: false, }, ], - target_version: [ + target: [ { name: 'fieldC', type: 'string', ecs: false, }, ], - merged_version: [ + merged: [ { name: 'fieldC', type: 'string', ecs: false, }, ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - required_fields: { - pick_version: 'RESOLVED', - resolved_value: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - required_fields: [ - { - name: 'resolved', - type: 'string', - ecs: false, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - required_fields: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'required_fields', + resolvedValue: [ { name: 'resolved', type: 'string', ecs: false, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + required_fields: [ + { + name: 'resolved', + type: 'string', + ecs: false, + }, + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts index 4a213ac440851..e83d9d3a82876 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function riskScoreField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"risk_score"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: {}, - upgrade: { - type: 'query', - risk_score: 10, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - risk_score: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 50, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 50, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', + risk_score: 10, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: {}, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 10, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 30, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: {}, + upgrade: { + type: 'query', risk_score: 30, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 50, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 50, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 10, + current: 10, + target: 30, + merged: 30, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedFieldsAfterUpgrade: { risk_score: 30 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 10, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 10, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { risk_score: 50, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 50, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 70, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 70, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 70, - }); - }); + }, + upgrade: { + type: 'query', + risk_score: 10, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 10, + current: 50, + target: 10, + merged: 50, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 50, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 50, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { risk_score: 50, - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', risk_score: 50, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 70, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 70, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 70, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 10, + current: 50, + target: 50, + merged: 50, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score: { - base_version: 10, - current_version: 50, - target_version: 30, - merged_version: 50, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 10, + current: 50, + target: 30, + merged: 50, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 70, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 70, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 70, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 30, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - risk_score: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 70, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 70, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 70, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 30, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score: 10, - }, - patch: { - risk_score: 50, - }, - upgrade: { - type: 'query', - risk_score: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score: { - current_version: 50, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score: 10, + }, + patch: { + risk_score: 50, + }, + upgrade: { + type: 'query', + risk_score: 30, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 50, + target: 30, + merged: 30, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score: { - pick_version: 'RESOLVED', - resolved_value: 70, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score: 70, - }); - expect(upgradedRule.body).toMatchObject({ - risk_score: 70, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { risk_score: 50 }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts index 2941098adf049..77f68493254fe 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/risk_score_mapping.ts @@ -5,124 +5,58 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function riskScoreMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"risk_score_mapping"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - risk_score_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score_mapping: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: {}, + upgrade: { + type: 'query', risk_score_mapping: [ { - field: 'resolved', + field: 'fieldA', operator: 'equals', - value: '50', - risk_score: 50, + value: '10', + risk_score: 10, }, ], - }); - expect(upgradedRule.body).toMatchObject({ - risk_score_mapping: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -130,58 +64,55 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, }, - patch: {}, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], + ], + }, + patch: {}, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ + ], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -189,7 +120,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - current_version: [ + current: [ { field: 'fieldA', operator: 'equals', @@ -197,7 +128,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - target_version: [ + target: [ { field: 'fieldB', operator: 'equals', @@ -205,7 +136,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -213,47 +144,70 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', risk_score_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - value: '30', - risk_score: 30, + value: '10', + risk_score: 10, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { risk_score_mapping: [ { field: 'fieldB', @@ -262,118 +216,27 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + upgrade: { + type: 'query', risk_score_mapping: [ { - field: 'resolved', + field: 'fieldA', operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - risk_score_mapping: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, + value: '10', + risk_score: 10, }, ], - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -381,7 +244,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -389,7 +252,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - target_version: [ + target: [ { field: 'fieldA', operator: 'equals', @@ -397,7 +260,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -405,47 +268,70 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', risk_score_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - value: '30', - risk_score: 30, + value: '10', + risk_score: 10, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { risk_score_mapping: [ { field: 'fieldB', @@ -454,118 +340,27 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + upgrade: { + type: 'query', risk_score_mapping: [ { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - risk_score_mapping: [ - { - field: 'resolved', + field: 'fieldB', operator: 'equals', - value: '50', - risk_score: 50, + value: '30', + risk_score: 30, }, ], - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -573,7 +368,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -581,7 +376,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - target_version: [ + target: [ { field: 'fieldB', operator: 'equals', @@ -589,7 +384,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -597,47 +392,70 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', risk_score_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - value: '30', - risk_score: 30, + value: '10', + risk_score: 10, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { risk_score_mapping: [ { field: 'fieldB', @@ -646,118 +464,28 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score_mapping: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', risk_score_mapping: [ { - field: 'resolved', + field: 'fieldC', operator: 'equals', value: '50', risk_score: 50, }, ], - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -765,7 +493,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 10, }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -773,7 +501,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - target_version: [ + target: [ { field: 'fieldC', operator: 'equals', @@ -781,7 +509,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -789,56 +517,16 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score_mapping: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - risk_score_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -846,112 +534,73 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], - }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - risk_score_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score_mapping: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { risk_score_mapping: [ { - field: 'resolved', + field: 'fieldB', operator: 'equals', - value: '50', - risk_score: 50, + value: '30', + risk_score: 30, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -959,69 +608,65 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldA', - operator: 'equals', - value: '10', - risk_score: 10, - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldA', + operator: 'equals', + value: '10', + risk_score: 10, }, - patch: { - risk_score_mapping: [ - { - field: 'fieldB', - operator: 'equals', - value: '30', - risk_score: 30, - }, - ], + ], + }, + patch: { + risk_score_mapping: [ + { + field: 'fieldB', + operator: 'equals', + value: '30', + risk_score: 30, }, - upgrade: { - type: 'query', - risk_score_mapping: [ - { - field: 'fieldC', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], + ], + }, + upgrade: { + type: 'query', + risk_score_mapping: [ + { + field: 'fieldC', + operator: 'equals', + value: '50', + risk_score: 50, }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - risk_score_mapping: { - current_version: [ + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [ { field: 'fieldB', operator: 'equals', @@ -1029,7 +674,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 30, }, ], - target_version: [ + target: [ { field: 'fieldC', operator: 'equals', @@ -1037,7 +682,7 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - merged_version: [ + merged: [ { field: 'fieldC', operator: 'equals', @@ -1045,56 +690,16 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - risk_score_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - risk_score_mapping: [ - { - field: 'resolved', - operator: 'equals', - value: '50', - risk_score: 50, - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - risk_score_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'risk_score_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -1102,8 +707,19 @@ export function riskScoreMappingField({ getService }: FtrProviderContext): void risk_score: 50, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + risk_score_mapping: [ + { + field: 'resolved', + operator: 'equals', + value: '50', + risk_score: 50, + }, + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts index 6cb1b4dac8d1c..afe5b1cac6821 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_name_override.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function ruleNameOverrideField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"rule_name_override"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - rule_name_override: 'fieldA', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - rule_name_override: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldA' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_name_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', rule_name_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA' }, + current: { field_name: 'fieldA' }, + target: { field_name: 'fieldB' }, + merged: { field_name: 'fieldB' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedFieldsAfterUpgrade: { rule_name_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldA', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldA' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { rule_name_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA' }, + current: { field_name: 'fieldB' }, + target: { field_name: 'fieldA' }, + merged: { field_name: 'fieldB' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedFieldsAfterUpgrade: { rule_name_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldB' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { rule_name_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', rule_name_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA' }, + current: { field_name: 'fieldB' }, + target: { field_name: 'fieldB' }, + merged: { field_name: 'fieldB' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedFieldsAfterUpgrade: { rule_name_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldC', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - base_version: { field_name: 'fieldA' }, - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldC' }, - merged_version: { field_name: 'fieldB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { field_name: 'fieldA' }, + current: { field_name: 'fieldB' }, + target: { field_name: 'fieldC' }, + merged: { field_name: 'fieldB' }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - rule_name_override: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - rule_name_override: 'fieldA', - }, - patch: { - rule_name_override: 'fieldB', - }, - upgrade: { - type: 'query', - rule_name_override: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_name_override: { - current_version: { field_name: 'fieldB' }, - target_version: { field_name: 'fieldC' }, - merged_version: { field_name: 'fieldC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + rule_name_override: 'fieldA', + }, + patch: { + rule_name_override: 'fieldB', + }, + upgrade: { + type: 'query', + rule_name_override: 'fieldC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { field_name: 'fieldB' }, + target: { field_name: 'fieldC' }, + merged: { field_name: 'fieldC' }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_name_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - rule_name_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - rule_name_override: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_name_override', + resolvedValue: { field_name: 'resolved' }, + expectedFieldsAfterUpgrade: { rule_name_override: 'resolved' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts index b6be69d397ee3..3efb3057920ab 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/rule_schedule.ts @@ -5,814 +5,449 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function ruleScheduleField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"rule_schedule"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: {}, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - rule_schedule: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { interval: '1h', from: 'now-2h', to: 'now' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-10m', to: 'now', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { interval: '1h', from: 'now-2h', to: 'now' }, + expectedFieldsAfterUpgrade: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: {}, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: {}, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { interval: '5m', from: 'now-10m', to: 'now', }, - current_version: { + current: { interval: '5m', from: 'now-10m', to: 'now', }, - target_version: { + target: { interval: '5m', from: 'now-15m', to: 'now', }, - merged_version: { + merged: { interval: '5m', from: 'now-15m', to: 'now', }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_schedule: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedFieldsAfterUpgrade: { interval: '5m', from: 'now-15m', to: 'now' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', interval: '5m', - from: 'now-15m', + from: 'now-10m', to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', interval: '5m', - from: 'now-15m', + from: 'now-10m', to: 'now', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { - interval: '1h', - from: 'now-2h', - to: 'now', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { interval: '5m', from: 'now-10m', to: 'now', }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { + current: { interval: '5m', from: 'now-20m', to: 'now', }, - target_version: { + target: { interval: '5m', from: 'now-10m', to: 'now', }, - merged_version: { + merged: { interval: '5m', from: 'now-20m', to: 'now', }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + + diffableRuleFieldName: 'rule_schedule', + expectedFieldsAfterUpgrade: { interval: '5m', from: 'now-20m', to: 'now' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', interval: '5m', - from: 'now-20m', + from: 'now-10m', to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', interval: '5m', from: 'now-20m', to: 'now', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { - interval: '1h', - from: 'now-2h', - to: 'now', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-20m', - to: 'now', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { interval: '5m', from: 'now-10m', to: 'now', }, - current_version: { + current: { interval: '5m', from: 'now-20m', to: 'now', }, - target_version: { + target: { interval: '5m', from: 'now-20m', to: 'now', }, - merged_version: { + merged: { interval: '5m', from: 'now-20m', to: 'now', }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedFieldsAfterUpgrade: { interval: '5m', from: 'now-20m', to: 'now' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', interval: '5m', - from: 'now-20m', + from: 'now-10m', to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '5m', + }, + patch: { from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', to: 'now', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { - interval: '1h', - from: 'now-2h', - to: 'now', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { interval: '5m', from: 'now-10m', to: 'now', }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - base_version: { - interval: '5m', - from: 'now-10m', - to: 'now', - }, - current_version: { + current: { interval: '5m', from: 'now-20m', to: 'now', }, - target_version: { + target: { interval: '5m', from: 'now-15m', to: 'now', }, - merged_version: { + merged: { interval: '5m', from: 'now-20m', to: 'now', }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { - interval: '1h', - from: 'now-2h', - to: 'now', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-20m', - to: 'now', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - rule_schedule: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { interval: '1h', from: 'now-2h', to: 'now' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-20m', to: 'now', - }); - }); + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - interval: '5m', - from: 'now-10m', - to: 'now', - }, - patch: { - from: 'now-20m', - }, - upgrade: { - type: 'query', - interval: '5m', - from: 'now-15m', - to: 'now', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - rule_schedule: { - current_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + interval: '5m', + from: 'now-10m', + to: 'now', + }, + patch: { + from: 'now-20m', + }, + upgrade: { + type: 'query', + interval: '5m', + from: 'now-15m', + to: 'now', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { interval: '5m', from: 'now-20m', to: 'now', }, - target_version: { + target: { interval: '5m', from: 'now-15m', to: 'now', }, - merged_version: { + merged: { interval: '5m', from: 'now-15m', to: 'now', }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - rule_schedule: { - pick_version: 'RESOLVED', - resolved_value: { - interval: '1h', - from: 'now-2h', - to: 'now', - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - expect(upgradedRule.body).toMatchObject({ - interval: '1h', - from: 'now-2h', - to: 'now', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'rule_schedule', + resolvedValue: { + interval: '1h', + from: 'now-2h', + to: 'now', + }, + expectedFieldsAfterUpgrade: { interval: '1h', from: 'now-2h', to: 'now' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts index 0249148c6d5df..78c954fcc20f2 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/setup.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function setupField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"setup"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: {}, - upgrade: { - type: 'query', - setup: 'some setup', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - setup: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: {}, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'some setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - setup: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'updated setup', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: {}, + upgrade: { + type: 'query', setup: 'updated setup', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'some setup', + current: 'some setup', + target: 'updated setup', + merged: 'updated setup', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedFieldsAfterUpgrade: { setup: 'updated setup' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'some setup', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'customized setup', - target_version: 'some setup', - merged_version: 'customized setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'customized setup', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { setup: 'customized setup', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + }, + upgrade: { + type: 'query', + setup: 'some setup', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'some setup', + current: 'customized setup', + target: 'some setup', + merged: 'customized setup', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedFieldsAfterUpgrade: { setup: 'customized setup' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'some setup', - current_version: 'updated setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { setup: 'updated setup', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', setup: 'updated setup', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'some setup', + current: 'updated setup', + target: 'updated setup', + merged: 'updated setup', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedFieldsAfterUpgrade: { setup: 'updated setup' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'line 1\nline 2', - }, - patch: { - setup: 'Customized line\nline 1\nline 2', - }, - upgrade: { - type: 'query', - setup: 'line 1\nline 3', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'line 1\nline 2', + }, + patch: { + setup: 'Customized line\nline 1\nline 2', + }, + upgrade: { + type: 'query', + setup: 'line 1\nline 3', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: 'line 1\nline 2', + current: 'Customized line\nline 1\nline 2', + target: 'line 1\nline 3', + merged: 'Customized line\nline 1\nline 3', }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - setup: { - base_version: 'line 1\nline 2', - current_version: 'Customized line\nline 1\nline 2', - target_version: 'line 1\nline 3', - merged_version: 'Customized line\nline 1\nline 3', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'updated setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - setup: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'updated setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - setup: 'some setup', - }, - patch: { - setup: 'customized setup', - }, - upgrade: { - type: 'query', - setup: 'updated setup', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - setup: { - current_version: 'customized setup', - target_version: 'updated setup', - merged_version: 'updated setup', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + setup: 'some setup', + }, + patch: { + setup: 'customized setup', + }, + upgrade: { + type: 'query', + setup: 'updated setup', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'customized setup', + target: 'updated setup', + merged: 'updated setup', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - setup: { - pick_version: 'RESOLVED', - resolved_value: 'Resolved setup', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - setup: 'Resolved setup', - }); - expect(upgradedRule.body).toMatchObject({ - setup: 'Resolved setup', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'setup', + resolvedValue: 'Resolved setup', + expectedFieldsAfterUpgrade: { setup: 'Resolved setup' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts index 1cfe4b5310d02..57183c1f76870 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity.ts @@ -5,652 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function severityField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"severity"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: {}, - upgrade: { - type: 'query', - severity: 'low', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - severity: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'high', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'high', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'high', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: {}, + upgrade: { + type: 'query', + severity: 'low', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'low', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'low', - target_version: 'high', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: {}, + upgrade: { + type: 'query', severity: 'high', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'high', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'medium', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'medium', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'medium', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'low', + current: 'low', + target: 'high', + merged: 'high', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedFieldsAfterUpgrade: { severity: 'high' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'low', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'low', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'medium', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: { severity: 'medium', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'critical', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'critical', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'critical', - }); - }); + }, + upgrade: { + type: 'query', + severity: 'low', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'low', + current: 'medium', + target: 'low', + merged: 'medium', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedFieldsAfterUpgrade: { severity: 'medium' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'medium', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'medium', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: { severity: 'medium', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', severity: 'medium', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'critical', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'critical', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'critical', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'low', + current: 'medium', + target: 'medium', + merged: 'medium', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedFieldsAfterUpgrade: { severity: 'medium' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity: { - base_version: 'low', - current_version: 'medium', - target_version: 'high', - merged_version: 'medium', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 'low', + current: 'medium', + target: 'high', + merged: 'medium', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'critical', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'critical', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'critical', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'medium', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - severity: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'critical', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'critical', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'critical', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'medium', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity: 'low', - }, - patch: { - severity: 'medium', - }, - upgrade: { - type: 'query', - severity: 'high', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity: { - current_version: 'medium', - target_version: 'high', - merged_version: 'high', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity: 'low', + }, + patch: { + severity: 'medium', + }, + upgrade: { + type: 'query', + severity: 'high', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'medium', + target: 'high', + merged: 'high', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity: { - pick_version: 'RESOLVED', - resolved_value: 'critical', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity: 'critical', - }); - expect(upgradedRule.body).toMatchObject({ - severity: 'critical', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity', + resolvedValue: 'critical', + expectedFieldsAfterUpgrade: { severity: 'critical' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts index 8cc8eefb21b2f..6cd09f94d9650 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/severity_mapping.ts @@ -5,124 +5,58 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function severityMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"severity_mapping"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - severity_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity_mapping: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: {}, + upgrade: { + type: 'query', severity_mapping: [ { - field: 'resolved', + field: 'fieldA', operator: 'equals', - severity: 'high', - value: '50', + severity: 'low', + value: '10', }, ], - }); - expect(upgradedRule.body).toMatchObject({ - severity_mapping: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -130,58 +64,55 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', }, - patch: {}, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'high', - value: '20', - }, - ], + ], + }, + patch: {}, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ + ], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -189,7 +120,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - current_version: [ + current: [ { field: 'fieldA', operator: 'equals', @@ -197,7 +128,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - target_version: [ + target: [ { field: 'fieldB', operator: 'equals', @@ -205,7 +136,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '20', }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -213,167 +144,99 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '20', }, ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'high', + value: '20', }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity_mapping: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ { - field: 'fieldB', + field: 'resolved', operator: 'equals', severity: 'high', - value: '20', + value: '50', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', severity_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - severity: 'high', - value: '20', - }, - ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, + severity: 'low', + value: '10', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { severity_mapping: [ { - field: 'resolved', + field: 'fieldB', operator: 'equals', - severity: 'high', - value: '50', + severity: 'medium', + value: '30', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', severity_mapping: [ { - field: 'resolved', + field: 'fieldA', operator: 'equals', - severity: 'high', - value: '50', + severity: 'low', + value: '10', }, ], - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -381,7 +244,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -389,7 +252,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - target_version: [ + target: [ { field: 'fieldA', operator: 'equals', @@ -397,7 +260,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -405,47 +268,70 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', severity_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - severity: 'medium', - value: '30', + severity: 'low', + value: '10', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { severity_mapping: [ { field: 'fieldB', @@ -454,118 +340,27 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + upgrade: { + type: 'query', severity_mapping: [ { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - severity_mapping: [ - { - field: 'resolved', + field: 'fieldB', operator: 'equals', - severity: 'high', - value: '50', + severity: 'medium', + value: '30', }, ], - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -573,7 +368,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -581,7 +376,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - target_version: [ + target: [ { field: 'fieldB', operator: 'equals', @@ -589,7 +384,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -597,47 +392,70 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'MERGED', - }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', }, + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', severity_mapping: [ { - field: 'fieldB', + field: 'fieldA', operator: 'equals', - severity: 'medium', - value: '30', + severity: 'low', + value: '10', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { severity_mapping: [ { field: 'fieldB', @@ -646,118 +464,28 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity_mapping: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', severity_mapping: [ { - field: 'resolved', + field: 'fieldC', operator: 'equals', severity: 'high', value: '50', }, ], - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [ { field: 'fieldA', operator: 'equals', @@ -765,7 +493,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '10', }, ], - current_version: [ + current: [ { field: 'fieldB', operator: 'equals', @@ -773,7 +501,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - target_version: [ + target: [ { field: 'fieldC', operator: 'equals', @@ -781,7 +509,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - merged_version: [ + merged: [ { field: 'fieldB', operator: 'equals', @@ -789,46 +517,16 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -836,122 +534,73 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - }); - expect(upgradedRule.body).toMatchObject({ - severity_mapping: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }); - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], - }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - severity_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity_mapping: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { severity_mapping: [ { - field: 'resolved', + field: 'fieldB', operator: 'equals', - severity: 'high', - value: '50', + severity: 'medium', + value: '30', }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -959,69 +608,65 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - severity_mapping: [ - { - field: 'fieldA', - operator: 'equals', - severity: 'low', - value: '10', - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + severity_mapping: [ + { + field: 'fieldA', + operator: 'equals', + severity: 'low', + value: '10', }, - patch: { - severity_mapping: [ - { - field: 'fieldB', - operator: 'equals', - severity: 'medium', - value: '30', - }, - ], + ], + }, + patch: { + severity_mapping: [ + { + field: 'fieldB', + operator: 'equals', + severity: 'medium', + value: '30', }, - upgrade: { - type: 'query', - severity_mapping: [ - { - field: 'fieldC', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], + ], + }, + upgrade: { + type: 'query', + severity_mapping: [ + { + field: 'fieldC', + operator: 'equals', + severity: 'high', + value: '50', }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - severity_mapping: { - current_version: [ + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [ { field: 'fieldB', operator: 'equals', @@ -1029,7 +674,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '30', }, ], - target_version: [ + target: [ { field: 'fieldC', operator: 'equals', @@ -1037,7 +682,7 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - merged_version: [ + merged: [ { field: 'fieldC', operator: 'equals', @@ -1045,56 +690,16 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - severity_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - severity_mapping: [ - { - field: 'resolved', - operator: 'equals', - severity: 'high', - value: '50', - }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - severity_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'severity_mapping', + resolvedValue: [ { field: 'resolved', operator: 'equals', @@ -1102,8 +707,19 @@ export function severityMappingField({ getService }: FtrProviderContext): void { value: '50', }, ], - }); - }); + expectedFieldsAfterUpgrade: { + severity_mapping: [ + { + field: 'resolved', + operator: 'equals', + severity: 'high', + value: '50', + }, + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts index b74d6c361b6ce..880ec3ed29f3a 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/tags.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function tagsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"tags"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagA'], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - tags: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: {}, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagA'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - tags: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['tagB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: {}, + upgrade: { + type: 'query', tags: ['tagB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['tagA'], + current: ['tagA'], + target: ['tagB'], + merged: ['tagB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedFieldsAfterUpgrade: { tags: ['tagB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagA'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagA'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['tagB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { tags: ['tagB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + }, + upgrade: { + type: 'query', + tags: ['tagA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['tagA'], + current: ['tagB'], + target: ['tagA'], + merged: ['tagB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedFieldsAfterUpgrade: { tags: ['tagB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagB'], - merged_version: ['tagB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { tags: ['tagB'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', tags: ['tagB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['tagA'], + current: ['tagB'], + target: ['tagB'], + merged: ['tagB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedFieldsAfterUpgrade: { tags: ['tagB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - tags: { - base_version: ['tagA'], - current_version: ['tagB'], - target_version: ['tagC'], - merged_version: ['tagB', 'tagC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: ['tagA'], + current: ['tagB'], + target: ['tagC'], + merged: ['tagB', 'tagC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagB'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - tags: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagB'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - tags: ['tagA'], - }, - patch: { - tags: ['tagB'], - }, - upgrade: { - type: 'query', - tags: ['tagC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - tags: { - current_version: ['tagB'], - target_version: ['tagC'], - merged_version: ['tagC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + tags: ['tagA'], + }, + patch: { + tags: ['tagB'], + }, + upgrade: { + type: 'query', + tags: ['tagC'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['tagB'], + target: ['tagC'], + merged: ['tagC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - tags: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - tags: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - tags: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'tags', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { tags: ['resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts index 3fddab56ad929..2e001b5322de0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/threat.ts @@ -5,132 +5,62 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function threatField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threat"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: {}, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + threat: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', }, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: {}, + upgrade: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticA', + id: 'tacticA', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ - threat: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { @@ -140,62 +70,61 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, }, - patch: {}, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], + ], + }, + patch: {}, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ + ], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [ { framework: 'something', tactic: { @@ -205,7 +134,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - current_version: [ + current: [ { framework: 'something', tactic: { @@ -215,7 +144,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - target_version: [ + target: [ { framework: 'something', tactic: { @@ -225,7 +154,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - merged_version: [ + merged: [ { framework: 'something', tactic: { @@ -235,183 +164,111 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat: { - pick_version: 'MERGED', + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', }, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'resolved', + id: 'resolved', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'tacticA', + id: 'tacticA', reference: 'reference', }, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticB', + id: 'tacticB', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticA', + id: 'tacticA', reference: 'reference', }, }, ], - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [ { framework: 'something', tactic: { @@ -421,7 +278,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - current_version: [ + current: [ { framework: 'something', tactic: { @@ -431,7 +288,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - target_version: [ + target: [ { framework: 'something', tactic: { @@ -441,7 +298,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - merged_version: [ + merged: [ { framework: 'something', tactic: { @@ -451,183 +308,111 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'MERGED', + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', }, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'resolved', + id: 'resolved', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'tacticA', + id: 'tacticA', reference: 'reference', }, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticB', + id: 'tacticB', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticB', + id: 'tacticB', reference: 'reference', }, }, ], - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [ { framework: 'something', tactic: { @@ -637,7 +422,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - current_version: [ + current: [ { framework: 'something', tactic: { @@ -647,7 +432,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - target_version: [ + target: [ { framework: 'something', tactic: { @@ -657,7 +442,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - merged_version: [ + merged: [ { framework: 'something', tactic: { @@ -667,183 +452,112 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'MERGED', + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', }, }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat: [ + ], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'resolved', + id: 'resolved', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + getService + ); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'tacticB', - id: 'tacticB', + name: 'tacticA', + id: 'tacticA', reference: 'reference', }, }, ], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticB', + id: 'tacticB', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticC', + id: 'tacticC', reference: 'reference', }, }, ], - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat: { - base_version: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [ { framework: 'something', tactic: { @@ -853,7 +567,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - current_version: [ + current: [ { framework: 'something', tactic: { @@ -863,7 +577,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - target_version: [ + target: [ { framework: 'something', tactic: { @@ -873,7 +587,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - merged_version: [ + merged: [ { framework: 'something', tactic: { @@ -883,48 +597,16 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { @@ -934,134 +616,81 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ - threat: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, }, - }, - ], - }); - }); + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], - }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + threat: [ { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', }, }, ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + }, + patch: { threat: [ { framework: 'something', tactic: { - name: 'resolved', - id: 'resolved', + name: 'tacticB', + id: 'tacticB', reference: 'reference', }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, + }, + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { @@ -1071,75 +700,73 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, + }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticA', - id: 'tacticA', - reference: 'reference', - }, - }, - ], + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticA', + id: 'tacticA', + reference: 'reference', + }, }, - patch: { - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticB', - id: 'tacticB', - reference: 'reference', - }, - }, - ], + ], + }, + patch: { + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticB', + id: 'tacticB', + reference: 'reference', + }, }, - upgrade: { - type: 'query', - threat: [ - { - framework: 'something', - tactic: { - name: 'tacticC', - id: 'tacticC', - reference: 'reference', - }, - }, - ], + ], + }, + upgrade: { + type: 'query', + threat: [ + { + framework: 'something', + tactic: { + name: 'tacticC', + id: 'tacticC', + reference: 'reference', + }, }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat: { - current_version: [ + ], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [ { framework: 'something', tactic: { @@ -1149,7 +776,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - target_version: [ + target: [ { framework: 'something', tactic: { @@ -1159,7 +786,7 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - merged_version: [ + merged: [ { framework: 'something', tactic: { @@ -1169,48 +796,16 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat: { - pick_version: 'RESOLVED', - resolved_value: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', - }, - }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat', + resolvedValue: [ { framework: 'something', tactic: { @@ -1220,20 +815,21 @@ export function threatField({ getService }: FtrProviderContext): void { }, }, ], - }); - expect(upgradedRule.body).toMatchObject({ - threat: [ - { - framework: 'something', - tactic: { - name: 'resolved', - id: 'resolved', - reference: 'reference', + expectedFieldsAfterUpgrade: { + threat: [ + { + framework: 'something', + tactic: { + name: 'resolved', + id: 'resolved', + reference: 'reference', + }, }, - }, - ], - }); - }); + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts index 783a38446538b..911500e0bb346 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timeline_template.ts @@ -5,689 +5,356 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function timelineTemplateField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"timeline_template"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: {}, - upgrade: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - timeline_template: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: {}, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timeline_template: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'B', - timeline_title: 'timelineB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: {}, + upgrade: { + type: 'query', timeline_id: 'B', timeline_title: 'timelineB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { timeline_id: 'A', timeline_title: 'timelineA' }, + current: { timeline_id: 'A', timeline_title: 'timelineA' }, + target: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged: { timeline_id: 'B', timeline_title: 'timelineB' }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedFieldsAfterUpgrade: { timeline_id: 'B', timeline_title: 'timelineB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'B', - timeline_title: 'timelineB', - }); - expect(upgradedRule.body).toMatchObject({ + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { timeline_id: 'B', timeline_title: 'timelineB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, + }, + upgrade: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { timeline_id: 'A', timeline_title: 'timelineA' }, + current: { timeline_id: 'B', timeline_title: 'timelineB' }, + target: { timeline_id: 'A', timeline_title: 'timelineA' }, + merged: { timeline_id: 'B', timeline_title: 'timelineB' }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedFieldsAfterUpgrade: { timeline_id: 'B', timeline_title: 'timelineB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { timeline_id: 'B', timeline_title: 'timelineB', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', timeline_id: 'B', timeline_title: 'timelineB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { timeline_id: 'A', timeline_title: 'timelineA' }, + current: { timeline_id: 'B', timeline_title: 'timelineB' }, + target: { timeline_id: 'B', timeline_title: 'timelineB' }, + merged: { timeline_id: 'B', timeline_title: 'timelineB' }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedFieldsAfterUpgrade: { timeline_id: 'B', timeline_title: 'timelineB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', + }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'C', - timeline_title: 'timelineC', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { timeline_id: 'A', timeline_title: 'timelineA' }, + current: { timeline_id: 'B', timeline_title: 'timelineB' }, + target: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged: { timeline_id: 'B', timeline_title: 'timelineB' }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timeline_template: { - base_version: { timeline_id: 'A', timeline_title: 'timelineA' }, - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - merged_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'B', - timeline_title: 'timelineB', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'B', + timeline_title: 'timelineB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - timeline_template: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timeline_id: 'A', - timeline_title: 'timelineA', - }, - patch: { - timeline_id: 'B', - timeline_title: 'timelineB', - }, - upgrade: { - type: 'query', - timeline_id: 'C', - timeline_title: 'timelineC', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timeline_id: 'A', + timeline_title: 'timelineA', + }, + patch: { + timeline_id: 'B', + timeline_title: 'timelineB', + }, + upgrade: { + type: 'query', + timeline_id: 'C', + timeline_title: 'timelineC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { timeline_id: 'B', timeline_title: 'timelineB' }, + target: { timeline_id: 'C', timeline_title: 'timelineC' }, + merged: { timeline_id: 'C', timeline_title: 'timelineC' }, }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timeline_template: { - current_version: { timeline_id: 'B', timeline_title: 'timelineB' }, - target_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - merged_version: { timeline_id: 'C', timeline_title: 'timelineC' }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timeline_template', + resolvedValue: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, + expectedFieldsAfterUpgrade: { + timeline_id: 'resolved', + timeline_title: 'timelineResolved', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timeline_template: { - pick_version: 'RESOLVED', - resolved_value: { timeline_id: 'resolved', timeline_title: 'timelineResolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - expect(upgradedRule.body).toMatchObject({ - timeline_id: 'resolved', - timeline_title: 'timelineResolved', - }); - }); + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts index fb89b5eef68ff..a6529cfcd5c58 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/common_fields/timestamp_override.ts @@ -5,650 +5,316 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function timestampOverrideField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"timestamp_override"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - timestamp_override: 'fieldA', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - timestamp_override: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldA', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timestamp_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'query', timestamp_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA', fallback_disabled: false }, + current: { field_name: 'fieldA', fallback_disabled: false }, + target: { field_name: 'fieldB', fallback_disabled: false }, + merged: { field_name: 'fieldB', fallback_disabled: false }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedFieldsAfterUpgrade: { timestamp_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldA', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldA', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { timestamp_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA', fallback_disabled: false }, + current: { field_name: 'fieldB', fallback_disabled: false }, + target: { field_name: 'fieldA', fallback_disabled: false }, + merged: { field_name: 'fieldB', fallback_disabled: false }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedFieldsAfterUpgrade: { timestamp_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldB', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { timestamp_override: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'query', timestamp_override: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { field_name: 'fieldA', fallback_disabled: false }, + current: { field_name: 'fieldB', fallback_disabled: false }, + target: { field_name: 'fieldB', fallback_disabled: false }, + merged: { field_name: 'fieldB', fallback_disabled: false }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedFieldsAfterUpgrade: { timestamp_override: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldC', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - base_version: { field_name: 'fieldA', fallback_disabled: false }, - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldC', fallback_disabled: false }, - merged_version: { field_name: 'fieldB', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { field_name: 'fieldA', fallback_disabled: false }, + current: { field_name: 'fieldB', fallback_disabled: false }, + target: { field_name: 'fieldC', fallback_disabled: false }, + merged: { field_name: 'fieldB', fallback_disabled: false }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - timestamp_override: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - timestamp_override: 'fieldA', - }, - patch: { - timestamp_override: 'fieldB', - }, - upgrade: { - type: 'query', - timestamp_override: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - timestamp_override: { - current_version: { field_name: 'fieldB', fallback_disabled: false }, - target_version: { field_name: 'fieldC', fallback_disabled: false }, - merged_version: { field_name: 'fieldC', fallback_disabled: false }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'query', + timestamp_override: 'fieldA', + }, + patch: { + timestamp_override: 'fieldB', + }, + upgrade: { + type: 'query', + timestamp_override: 'fieldC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { field_name: 'fieldB', fallback_disabled: false }, + target: { field_name: 'fieldC', fallback_disabled: false }, + merged: { field_name: 'fieldC', fallback_disabled: false }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - timestamp_override: { - pick_version: 'RESOLVED', - resolved_value: { field_name: 'resolved', fallback_disabled: false }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - timestamp_override: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - timestamp_override: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'timestamp_override', + resolvedValue: { field_name: 'resolved', fallback_disabled: false }, + expectedFieldsAfterUpgrade: { timestamp_override: 'resolved' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/test_helpers.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/test_helpers.ts new file mode 100644 index 0000000000000..48302fa6ef8a3 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/test_helpers.ts @@ -0,0 +1,546 @@ +/* + * 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 expect from 'expect'; +import { isUndefined, omitBy } from 'lodash'; +import type { + PartialRuleDiff, + RuleResponse, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { + DEFAULT_RULE_UPDATE_VERSION, + DEFAULT_TEST_RULE_ID, + RuleUpgradeAssets, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { + fetchFirstPrebuiltRuleUpgradeReviewDiff, + performUpgradePrebuiltRules, +} from '../../../../../utils'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; + +export interface TestFieldRuleUpgradeAssets extends RuleUpgradeAssets { + removeInstalledAssets?: boolean; +} + +interface FieldDiffValueVersions { + base: unknown; + current: unknown; + target: unknown; + merged: unknown; +} + +interface MissingHistoricalRuleVersionsFieldDiffValueVersions { + current: unknown; + target: unknown; + merged: unknown; +} + +interface TestFieldUpgradeReviewParams { + ruleUpgradeAssets: TestFieldRuleUpgradeAssets; + diffableRuleFieldName: string; +} + +type ExpectedDiffOutcome = + | { + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate; + expectedFieldDiffValues: FieldDiffValueVersions; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate; + expectedFieldDiffValues: FieldDiffValueVersions; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate; + expectedFieldDiffValues: FieldDiffValueVersions; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate; + isSolvableConflict: boolean; + expectedFieldDiffValues: FieldDiffValueVersions; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate; + } + | { + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate; + expectedFieldDiffValues: MissingHistoricalRuleVersionsFieldDiffValueVersions; + }; + +/** + * Creates a test to assert rule upgrade review endpoint returns an expected result. + * + * CAUTION: The function expected provided `ruleUpgradeAssets` defined according to the `expectedDiffOutcome`. + * In the other words it means `ruleUpgradeAssets` should define a proper rule upgrade state for + * a `fieldName` like non-customized field without upgrade or customized field with an upgrade resulting + * in a conflict. + */ +export function testFieldUpgradeReview( + params: TestFieldUpgradeReviewParams & ExpectedDiffOutcome, + getService: FtrProviderContext['getService'] +): void { + const supertest = getService('supertest'); + const testName = + params.expectedDiffOutcome === ThreeWayDiffOutcome.StockValueNoUpdate || + params.expectedDiffOutcome === ThreeWayDiffOutcome.MissingBaseNoUpdate + ? 'does NOT return upgrade review' + : 'returns upgrade review'; + + it(testName, async () => { + await setUpRuleUpgrade({ + assets: params.ruleUpgradeAssets, + removeInstalledAssets: params.ruleUpgradeAssets.removeInstalledAssets ?? false, + deps: { + es: getService('es'), + supertest, + log: getService('log'), + }, + }); + + const diff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + switch (params.expectedDiffOutcome) { + case ThreeWayDiffOutcome.StockValueNoUpdate: + expectAAAFieldDiff(diff, { diffableRuleFieldName: params.diffableRuleFieldName }); + break; + + case ThreeWayDiffOutcome.StockValueCanUpdate: + expectAABFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + break; + + case ThreeWayDiffOutcome.CustomizedValueNoUpdate: + expectABAFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + break; + + case ThreeWayDiffOutcome.CustomizedValueSameUpdate: + expectABBFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + break; + + case ThreeWayDiffOutcome.CustomizedValueCanUpdate: + if (params.isSolvableConflict) { + expectSolvableABCFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + } else { + expectNonSolvableABCFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + } + break; + + case ThreeWayDiffOutcome.MissingBaseNoUpdate: + expectMissingBaseAAFieldDiff(diff, { diffableRuleFieldName: params.diffableRuleFieldName }); + break; + + case ThreeWayDiffOutcome.MissingBaseCanUpdate: + expectMissingBaseABFieldDiff(diff, { + diffableRuleFieldName: params.diffableRuleFieldName, + valueVersions: params.expectedFieldDiffValues, + }); + break; + } + }); +} + +interface TestFieldUpgradesToMergedValueParams { + ruleUpgradeAssets: TestFieldRuleUpgradeAssets; + diffableRuleFieldName: string; + expectedFieldsAfterUpgrade: Partial; +} + +/** + * Creates a test to assert rule's `fieldName` upgrades to merged value. + * + * CAUTION: The function expected provided `ruleUpgradeAssets` defined according to the `expectedDiffOutcome`. + * In the other words it means `ruleUpgradeAssets` should define a proper rule upgrade state for + * a `fieldName` like non-customized field without upgrade or customized field with an upgrade resulting + * in a conflict. + * + * `mergedValue` must be conformed with `ruleUpgradeAssets`. + */ +export function testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName, + expectedFieldsAfterUpgrade, + }: TestFieldUpgradesToMergedValueParams, + getService: FtrProviderContext['getService'] +): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + securitySolutionApi, + }; + + it('upgrades to MERGED value', async () => { + await setUpRuleUpgrade({ + assets: ruleUpgradeAssets, + removeInstalledAssets: ruleUpgradeAssets.removeInstalledAssets ?? false, + deps, + }); + + const hasRuleFieldsToPatch = Object.keys(ruleUpgradeAssets.patch).length > 0; + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: ruleUpgradeAssets.upgrade.rule_id ?? DEFAULT_TEST_RULE_ID, + revision: hasRuleFieldsToPatch ? 1 : 0, + version: ruleUpgradeAssets.upgrade.version ?? DEFAULT_RULE_UPDATE_VERSION, + fields: { + [diffableRuleFieldName]: { + pick_version: 'MERGED', + }, + }, + }, + ], + }); + + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expectRuleFields(response.results.updated[0], expectedFieldsAfterUpgrade); + expectRuleFields(upgradedRule.body, expectedFieldsAfterUpgrade); + }); +} + +interface TestFieldUpgradesToResolvedValueParams { + ruleUpgradeAssets: TestFieldRuleUpgradeAssets; + diffableRuleFieldName: string; + resolvedValue: unknown; + expectedFieldsAfterUpgrade: Partial; +} + +/** + * Creates a test to assert rule's `fieldName` upgrades to a resolved value. + * + * Since `mergedValue` depends on the input data and a diff algorithm the function + * expect `mergedValue` to be provided. + * + * CAUTION: The function expected provided `ruleUpgradeAssets` defined according to the `expectedDiffOutcome`. + * In the other words it means `ruleUpgradeAssets` should define a proper rule upgrade state for + * a `fieldName` like non-customized field without upgrade or customized field with an upgrade resulting + * in a conflict. + */ +export function testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName, + resolvedValue, + expectedFieldsAfterUpgrade, + }: TestFieldUpgradesToResolvedValueParams, + getService: FtrProviderContext['getService'] +): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + + const deps = { + es, + supertest, + log, + securitySolutionApi, + }; + + it('upgrades to RESOLVED value', async () => { + await setUpRuleUpgrade({ + assets: ruleUpgradeAssets, + removeInstalledAssets: ruleUpgradeAssets.removeInstalledAssets ?? false, + deps, + }); + + const hasRuleFieldsToPatch = Object.keys(ruleUpgradeAssets.patch).length > 0; + + const response = await performUpgradePrebuiltRules(deps.es, deps.supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: ruleUpgradeAssets.upgrade.rule_id ?? DEFAULT_TEST_RULE_ID, + revision: hasRuleFieldsToPatch ? 1 : 0, + version: ruleUpgradeAssets.upgrade.version ?? DEFAULT_RULE_UPDATE_VERSION, + fields: { + [diffableRuleFieldName]: { + pick_version: 'RESOLVED', + resolved_value: resolvedValue, + }, + }, + }, + ], + }); + + const upgradedRule = await deps.securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expectRuleFields(response.results.updated[0], expectedFieldsAfterUpgrade); + expectRuleFields(upgradedRule.body, expectedFieldsAfterUpgrade); + }); +} + +interface FieldAbsenceAssertParams { + diffableRuleFieldName: string; +} + +/** + * Asserts provided non-customized `diffableRuleFieldName` isn't presented + * in the diff (`AAA` diff case) + */ +function expectAAAFieldDiff( + ruleDiff: PartialRuleDiff, + fieldAssertParams: FieldAbsenceAssertParams +): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 1, // counts version field + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).not.toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: expect.anything(), + }); +} + +interface FieldAssertParams { + diffableRuleFieldName: string; + valueVersions: FieldDiffValueVersions; +} + +/** + * Asserts provided non-customized `diffableRuleFieldName` doesn't have a conflict + * and ready for upgrade (`AAB` diff case) + */ +function expectAABFieldDiff(ruleDiff: PartialRuleDiff, fieldAssertParams: FieldAssertParams): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 2, // counts + version field + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + base_version: fieldAssertParams.valueVersions.base, + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + }, + isUndefined + ), + }); +} + +/** + * Asserts provided customized `diffableRuleFieldName` without an upgrade doesn't have a conflict + * and ready for upgrade (`ABA` diff case) + */ +function expectABAFieldDiff(ruleDiff: PartialRuleDiff, fieldAssertParams: FieldAssertParams): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 1, // counts version field + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + base_version: fieldAssertParams.valueVersions.base, + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + }, + isUndefined + ), + }); +} + +/** + * Asserts provided customized `diffableRuleFieldName` with the matching update + * doesn't have a conflict and is ready for upgrade (`ABB` diff case) + */ +function expectABBFieldDiff(ruleDiff: PartialRuleDiff, fieldAssertParams: FieldAssertParams): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 1, // counts version field + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + base_version: fieldAssertParams.valueVersions.base, + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + }, + isUndefined + ), + }); +} + +/** + * Asserts provided customized `diffableRuleFieldName` with an upgrade + * has a solvable conflict (`ABC` diff case) + */ +function expectSolvableABCFieldDiff( + ruleDiff: PartialRuleDiff, + fieldAssertParams: FieldAssertParams +): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 2, // counts + version field + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + base_version: fieldAssertParams.valueVersions.base, + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Merged, + conflict: ThreeWayDiffConflict.SOLVABLE, + }, + isUndefined + ), + }); +} + +/** + * Asserts provided customized `diffableRuleFieldName` with an upgrade + * has a non-solvable conflict (`ABC` diff case) + */ +function expectNonSolvableABCFieldDiff( + ruleDiff: PartialRuleDiff, + fieldAssertParams: FieldAssertParams +): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 2, // counts + version field + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 1, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + base_version: fieldAssertParams.valueVersions.base, + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + }, + isUndefined + ), + }); +} + +/** + * With historical versions missing + * Asserts provided `diffableRuleFieldName` with an upgrade + * has the matching upgrade (`-AA` diff case) + */ +function expectMissingBaseAAFieldDiff( + ruleDiff: PartialRuleDiff, + fieldAssertParams: FieldAbsenceAssertParams +): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 1, // counts version field + num_fields_with_conflicts: 0, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).not.toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: expect.anything(), + }); +} + +interface MissingBaseFieldAssertParams { + diffableRuleFieldName: string; + valueVersions: MissingHistoricalRuleVersionsFieldDiffValueVersions; +} + +/** + * With historical versions missing + * Asserts provided `diffableRuleFieldName` with an upgrade + * has an upgrade (`-AB` diff case) + */ +function expectMissingBaseABFieldDiff( + ruleDiff: PartialRuleDiff, + fieldAssertParams: MissingBaseFieldAssertParams +): void { + expect(ruleDiff).toMatchObject({ + num_fields_with_updates: 2, // counts + version field + num_fields_with_conflicts: 1, + num_fields_with_non_solvable_conflicts: 0, + }); + expect(ruleDiff.fields).toMatchObject({ + [fieldAssertParams.diffableRuleFieldName]: omitBy( + { + current_version: fieldAssertParams.valueVersions.current, + target_version: fieldAssertParams.valueVersions.target, + merged_version: fieldAssertParams.valueVersions.merged, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + }, + isUndefined + ), + }); +} + +/** + * Assertion helper to assert `fields` are presented in `maybeRule`. + * + * For any field's undefined value expectation is built to assert absence of the field. + */ +function expectRuleFields(maybeRule: Record, fields: Partial): void { + for (const [fieldName, value] of Object.entries(fields)) { + if (value === undefined) { + expect(maybeRule).not.toMatchObject({ + [fieldName]: expect.anything(), + }); + } else { + expect(maybeRule).toMatchObject({ + [fieldName]: value, + }); + } + } +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts index 5093191d81a7a..16153505e5561 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/anomaly_threshold.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function anomalyThresholdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"anomaly_threshold"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: {}, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - anomaly_threshold: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 30, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 30, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 30, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 30, + expectedFieldsAfterUpgrade: { anomaly_threshold: 30 }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: {}, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 10, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 20, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: {}, + upgrade: { + type: 'machine_learning', anomaly_threshold: 20, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 30, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 30, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 30, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 10, + current: 10, + target: 20, + merged: 20, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedFieldsAfterUpgrade: { anomaly_threshold: 20 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 30, + expectedFieldsAfterUpgrade: { anomaly_threshold: 30 }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 10, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 20, - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', anomaly_threshold: 20, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 30, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 30, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 30, - }); - }); + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 10, + current: 20, + target: 10, + merged: 20, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedFieldsAfterUpgrade: { anomaly_threshold: 20 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 30, + expectedFieldsAfterUpgrade: { anomaly_threshold: 30 }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 20, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', anomaly_threshold: 20, - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'machine_learning', anomaly_threshold: 20, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 30, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 30, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 30, - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 10, + current: 20, + target: 20, + merged: 20, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedFieldsAfterUpgrade: { anomaly_threshold: 20 }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 30, + expectedFieldsAfterUpgrade: { anomaly_threshold: 30 }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 30, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - base_version: 10, - current_version: 20, - target_version: 30, - merged_version: 20, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 10, + current: 20, + target: 30, + merged: 20, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 50, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 50, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { anomaly_threshold: 50 }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - anomaly_threshold: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 30, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 30, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 30, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { anomaly_threshold: 50 }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - anomaly_threshold: 10, - }, - patch: { - type: 'machine_learning', - anomaly_threshold: 20, - }, - upgrade: { - type: 'machine_learning', - anomaly_threshold: 30, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - anomaly_threshold: { - current_version: 20, - target_version: 30, - merged_version: 30, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + anomaly_threshold: 10, + }, + patch: { + type: 'machine_learning', + anomaly_threshold: 20, + }, + upgrade: { + type: 'machine_learning', + anomaly_threshold: 30, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 20, + target: 30, + merged: 30, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - anomaly_threshold: { - pick_version: 'RESOLVED', - resolved_value: 50, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - anomaly_threshold: 50, - }); - expect(upgradedRule.body).toMatchObject({ - anomaly_threshold: 50, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'anomaly_threshold', + resolvedValue: 50, + expectedFieldsAfterUpgrade: { anomaly_threshold: 50 }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts index 9f82f3ace5e85..1e1f6795c5408 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/eql_query.ts @@ -5,788 +5,464 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function eqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"eql_query"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: {}, - upgrade: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - eql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'process where process.name == "regsvr32.exe"', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'process where process.name == "regsvr32.exe"', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: {}, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: {}, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { query: 'any where true', language: 'eql', filters: [], }, - current_version: { + current: { query: 'any where true', language: 'eql', filters: [], }, - target_version: { + target: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - merged_version: { + merged: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - eql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'process where process.name == "regsvr32.exe"', + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { query: 'any where true', language: 'eql', filters: [], }, - current_version: { + current: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - target_version: { + target: { query: 'any where true', language: 'eql', filters: [], }, - merged_version: { + merged: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'process where process.name == "regsvr32.exe"', + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + query: 'process where process.name == "regsvr32.exe"', + }, + upgrade: { + type: 'eql', query: 'process where process.name == "regsvr32.exe"', language: 'eql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'process where process.name == "regsvr32.exe"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { query: 'any where true', language: 'eql', filters: [], }, - current_version: { + current: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - target_version: { + target: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - merged_version: { + merged: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'process where process.name == "regsvr32.exe"', + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', query: 'process where process.name == "regsvr32.exe"', language: 'eql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - eql_query: { - base_version: { + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { query: 'any where true', language: 'eql', filters: [], }, - current_version: { + current: { query: 'host where host.name == "something"', language: 'eql', filters: [], }, - target_version: { + target: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - merged_version: { + merged: { query: 'host where host.name == "something"', language: 'eql', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'host where host.name == "something"', - language: 'eql', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - eql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'host where host.name == "something"', language: 'eql', - }); - }); + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'eql', - query: 'any where true', - language: 'eql', - }, - patch: { - query: 'host where host.name == "something"', - }, - upgrade: { - type: 'eql', - query: 'process where process.name == "regsvr32.exe"', - language: 'eql', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - eql_query: { - current_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'eql', + query: 'any where true', + language: 'eql', + }, + patch: { + query: 'host where host.name == "something"', + }, + upgrade: { + type: 'eql', + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { query: 'host where host.name == "something"', language: 'eql', filters: [], }, - target_version: { + target: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - merged_version: { + merged: { query: 'process where process.name == "regsvr32.exe"', language: 'eql', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - eql_query: { - pick_version: 'RESOLVED', - resolved_value: { - query: 'resolved where true', - language: 'eql', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved where true', - language: 'eql', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'eql_query', + resolvedValue: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + filters: [], + }, + expectedFieldsAfterUpgrade: { + query: 'process where process.name == "regsvr32.exe"', + language: 'eql', + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts index 674ce62a13d24..f59086d07560f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/esql_query.ts @@ -5,751 +5,397 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function esqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"esql_query"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: {}, - upgrade: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - esql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: {}, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: {}, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { query: 'FROM indexA METADATA _id', language: 'esql', }, - current_version: { + current: { query: 'FROM indexA METADATA _id', language: 'esql', }, - target_version: { + target: { query: 'FROM indexB METADATA _id', language: 'esql', }, - merged_version: { + merged: { query: 'FROM indexB METADATA _id', language: 'esql', }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - esql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedFieldsAfterUpgrade: { query: 'FROM indexB METADATA _id', language: 'esql' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM indexB METADATA _id', + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + type: 'esql', query: 'FROM indexB METADATA _id', language: 'esql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', + }, + upgrade: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { query: 'FROM indexA METADATA _id', language: 'esql', }, - patch: { - type: 'esql', + current: { query: 'FROM indexB METADATA _id', language: 'esql', }, - upgrade: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { + target: { query: 'FROM indexA METADATA _id', language: 'esql', }, - current_version: { + merged: { query: 'FROM indexB METADATA _id', language: 'esql', }, - target_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedFieldsAfterUpgrade: { query: 'FROM indexB METADATA _id', language: 'esql' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM indexB METADATA _id', + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + type: 'esql', query: 'FROM indexB METADATA _id', language: 'esql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', language: 'esql', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { query: 'FROM indexA METADATA _id', language: 'esql', }, - patch: { - type: 'esql', + current: { query: 'FROM indexB METADATA _id', language: 'esql', }, - upgrade: { - type: 'esql', + target: { query: 'FROM indexB METADATA _id', language: 'esql', }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { + merged: { query: 'FROM indexB METADATA _id', language: 'esql', }, - target_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedFieldsAfterUpgrade: { query: 'FROM indexB METADATA _id', language: 'esql' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM indexB METADATA _id', + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: { + type: 'esql', query: 'FROM indexB METADATA _id', language: 'esql', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', language: 'esql', - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { query: 'FROM indexA METADATA _id', language: 'esql', }, - patch: { - type: 'esql', + current: { query: 'FROM indexB METADATA _id', language: 'esql', }, - upgrade: { - type: 'esql', + target: { query: 'FROM indexC METADATA _id', language: 'esql', }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - esql_query: { - base_version: { - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - current_version: { + merged: { query: 'FROM indexB METADATA _id', language: 'esql', }, - target_version: { - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - merged_version: { - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - esql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexB METADATA _id', language: 'esql', - }); - }); + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'esql', - query: 'FROM indexA METADATA _id', - language: 'esql', - }, - patch: { - type: 'esql', - query: 'FROM indexB METADATA _id', - language: 'esql', - }, - upgrade: { - type: 'esql', - query: 'FROM indexC METADATA _id', - language: 'esql', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - esql_query: { - current_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'esql', + query: 'FROM indexA METADATA _id', + language: 'esql', + }, + patch: { + type: 'esql', + query: 'FROM indexB METADATA _id', + language: 'esql', + }, + upgrade: { + type: 'esql', + query: 'FROM indexC METADATA _id', + language: 'esql', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { query: 'FROM indexB METADATA _id', language: 'esql', }, - target_version: { + target: { query: 'FROM indexC METADATA _id', language: 'esql', }, - merged_version: { + merged: { query: 'FROM indexC METADATA _id', language: 'esql', }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - esql_query: { - pick_version: 'RESOLVED', - resolved_value: { query: 'FROM resolved METADATA _id', language: 'esql' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'FROM resolved METADATA _id', - language: 'esql', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'esql_query', + resolvedValue: { query: 'FROM resolved METADATA _id', language: 'esql' }, + expectedFieldsAfterUpgrade: { query: 'FROM resolved METADATA _id', language: 'esql' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts index 27ef929aaab79..6362fd474b441 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/history_window_start.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function historyWindowStartField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"history_window_start"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: {}, - upgrade: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - history_window_start: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-30m', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30m', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-30m', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-30m', + expectedFieldsAfterUpgrade: { history_window_start: 'now-30m' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: {}, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-1h', - target_version: 'now-30m', - merged_version: 'now-30m', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - history_window_start: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30m', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: {}, + upgrade: { + type: 'new_terms', history_window_start: 'now-30m', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-2h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-2h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-2h', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'now-1h', + current: 'now-1h', + target: 'now-30m', + merged: 'now-30m', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedFieldsAfterUpgrade: { history_window_start: 'now-30m' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-2h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-2h' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-1h', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', history_window_start: 'now-2h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-2h', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-30h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-30h', - }); - }); + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'now-1h', + current: 'now-2h', + target: 'now-1h', + merged: 'now-2h', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedFieldsAfterUpgrade: { history_window_start: 'now-2h' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-5h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-5h' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-2h', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', history_window_start: 'now-2h', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'new_terms', history_window_start: 'now-2h', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-30h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-30h', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'now-1h', + current: 'now-2h', + target: 'now-2h', + merged: 'now-2h', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedFieldsAfterUpgrade: { history_window_start: 'now-2h' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-5h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-5h' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - history_window_start: { - base_version: 'now-1h', - current_version: 'now-2h', - target_version: 'now-30m', - merged_version: 'now-2h', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 'now-1h', + current: 'now-2h', + target: 'now-30m', + merged: 'now-2h', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-30h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-30h', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-5h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-5h' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - history_window_start: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-30h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-30h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-30h', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-5h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-5h' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - history_window_start: 'now-1h', - }, - patch: { - type: 'new_terms', - history_window_start: 'now-2h', - }, - upgrade: { - type: 'new_terms', - history_window_start: 'now-30m', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - history_window_start: { - current_version: 'now-2h', - target_version: 'now-30m', - merged_version: 'now-30m', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + history_window_start: 'now-1h', + }, + patch: { + type: 'new_terms', + history_window_start: 'now-2h', + }, + upgrade: { + type: 'new_terms', + history_window_start: 'now-30m', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'now-2h', + target: 'now-30m', + merged: 'now-30m', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - history_window_start: { - pick_version: 'RESOLVED', - resolved_value: 'now-5h', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - history_window_start: 'now-5h', - }); - expect(upgradedRule.body).toMatchObject({ - history_window_start: 'now-5h', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'history_window_start', + resolvedValue: 'now-5h', + expectedFieldsAfterUpgrade: { history_window_start: 'now-5h' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts index b434728d74def..6f2d4a8809a77 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.inline_query.ts @@ -5,353 +5,91 @@ * 2.0. */ -import expect from 'expect'; import { KqlQueryType, - ModeEnum, - ThreeWayDiffConflict, ThreeWayDiffOutcome, - ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; const RULE_TYPES = ['query', 'threat_match', 'threshold', 'new_terms'] as const; export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - for (const ruleType of RULE_TYPES) { describe(`"kql_query" with inline query for ${ruleType} rule`, () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { describe('without filters', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { type: ruleType, - query: 'resolved:*', + query: 'process.name:*.exe', language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ + }, + patch: {}, + upgrade: { type: ruleType, - query: 'resolved:*', + query: 'process.name:*.exe', language: 'kuery', - }); - }); - }); - - describe('with filters', () => { - describe('and filters have "alias" field set to null for installed rules', () => { - it('does NOT return upgrade review', async () => { - const FILTER = { - meta: { - negate: false, - disabled: false, - type: 'phrase', - key: 'test', - params: { - query: 'value', - }, - }, - query: { - term: { - field: 'value', - }, - }, - }; - - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - filters: [FILTER], - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - patch: { - type: ruleType, - filters: [ - { - ...FILTER, - meta: { - ...FILTER.meta, - alias: null, - }, - }, - ], - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - upgrade: { - type: ruleType, - filters: [FILTER], - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - }, - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - }); - }); - }); - - describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - }, - patch: {}, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }, }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); + }; - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { - query: 'process.name:*.exe', - language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], - }, - current_version: { - query: 'process.name:*.exe', - language: 'kuery', + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { type: KqlQueryType.inline_query, - filters: [], - }, - target_version: { - query: 'process.name:*.sys', + query: 'resolved:*', language: 'kuery', - type: KqlQueryType.inline_query, filters: [], }, - merged_version: { - query: 'process.name:*.sys', + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', language: 'kuery', - type: KqlQueryType.inline_query, - filters: [], }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); + getService + ); }); - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, + describe('with filters', () => { + describe('and filters have "alias" field set to null for installed rules', () => { + const FILTER = { + meta: { + negate: false, + disabled: false, + type: 'phrase', + key: 'test', + params: { + query: 'value', }, }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, + query: { + term: { + field: 'value', }, }, - ], - }); + }; - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - }); - }); - - describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { installed: { type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', + filters: [FILTER], ...(ruleType === 'threshold' ? { threshold: { @@ -363,7 +101,15 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }, patch: { type: ruleType, - query: '*:*', + filters: [ + { + ...FILTER, + meta: { + ...FILTER.meta, + alias: null, + }, + }, + ], ...(ruleType === 'threshold' ? { threshold: { @@ -375,8 +121,7 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo }, upgrade: { type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', + filters: [FILTER], ...(ruleType === 'threshold' ? { threshold: { @@ -386,661 +131,576 @@ export function inlineQueryKqlQueryField({ getService }: FtrProviderContext): vo } : {}), }, - }, - deps, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); }); }); + }); - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { + describe('non-customized w/ an upgrade (AAB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + }, + patch: {}, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { query: 'process.name:*.exe', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - current_version: { - query: '*:*', + current: { + query: 'process.name:*.exe', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - target_version: { - query: 'process.name:*.exe', + target: { + query: 'process.name:*.sys', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - merged_version: { - query: '*:*', + merged: { + query: 'process.name:*.sys', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { type: ruleType, - query: '*:*', + query: 'process.name:*.exe', language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + patch: { type: ruleType, query: '*:*', - language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', + } + : {}), + }, + upgrade: { + type: ruleType, + query: 'process.name:*.exe', language: 'kuery', - }); - }); - }); - - describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { query: 'process.name:*.exe', language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), + type: KqlQueryType.inline_query, + filters: [], }, - patch: { - type: ruleType, + current: { query: '*:*', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], }, - upgrade: { - type: ruleType, + target: { + query: 'process.name:*.exe', + language: 'kuery', + type: KqlQueryType.inline_query, + filters: [], + }, + merged: { query: '*:*', language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), + type: KqlQueryType.inline_query, + filters: [], }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { type: ruleType, query: '*:*', language: 'kuery' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); + }); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + patch: { + type: ruleType, + query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + upgrade: { + type: ruleType, + query: '*:*', + language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { query: 'process.name:*.exe', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - current_version: { + current: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - target_version: { + target: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - merged_version: { + merged: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { type: ruleType, query: '*:*', language: 'kuery' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); + }); - expect(response.results.updated[0]).toMatchObject({ + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { type: ruleType, - query: '*:*', + query: 'process.name:*.exe', language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + patch: { type: ruleType, query: '*:*', - language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', + } + : {}), + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', language: 'kuery', - }); - }); - }); - - describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - patch: { - type: ruleType, - query: '*:*', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - base_version: { + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { query: 'process.name:*.exe', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - current_version: { + current: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - target_version: { + target: { query: 'process.name:*.sys', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - merged_version: { + merged: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - patch: { - type: ruleType, - query: 'process.name:*.sys', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - kql_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: ruleType, + query: 'process.name:*.exe', language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + patch: { + type: ruleType, + query: 'process.name:*.sys', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', language: 'kuery', - }); - }); + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - query: 'process.name:*.exe', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - patch: { - type: ruleType, - query: '*:*', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - upgrade: { - type: ruleType, - query: 'process.name:*.sys', - language: 'kuery', - ...(ruleType === 'threshold' - ? { - threshold: { - value: 10, - field: 'fieldA', - }, - } - : {}), - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - kql_query: { - current_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: ruleType, + query: 'process.name:*.exe', + language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + patch: { + type: ruleType, + query: '*:*', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + upgrade: { + type: ruleType, + query: 'process.name:*.sys', + language: 'kuery', + ...(ruleType === 'threshold' + ? { + threshold: { + value: 10, + field: 'fieldA', + }, + } + : {}), + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { query: '*:*', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - target_version: { + target: { query: 'process.name:*.sys', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - merged_version: { + merged: { query: 'process.name:*.sys', language: 'kuery', type: KqlQueryType.inline_query, filters: [], }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - kql_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - query: 'resolved:*', - language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { + type: ruleType, + query: 'resolved:*', + language: 'kuery', + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts index 4cb38ace95ac5..faacc1ea63ea8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/kql_query.saved_query.ts @@ -7,716 +7,384 @@ // Temporally comment contents until https://github.com/elastic/kibana/issues/209343 is fixed -// import expect from 'expect'; -// import { -// KqlQueryType, -// ModeEnum, -// ThreeWayDiffConflict, -// ThreeWayDiffOutcome, -// ThreeWayMergeOutcome, -// } from '@kbn/security-solution-plugin/common/api/detection_engine'; -// import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -// import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../utils'; -// import { -// DEFAULT_TEST_RULE_ID, -// setUpRuleUpgrade, -// } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; - -// export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { -// const es = getService('es'); -// const supertest = getService('supertest'); -// const log = getService('log'); -// const securitySolutionApi = getService('securitySolutionApi'); - -// const deps = { -// es, -// supertest, -// log, -// }; - -// describe('"kql_query" with saved query', () => { -// describe('non-customized w/o an upgrade (AAA diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: {}, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// }, -// deps, -// }); -// }); - -// it('does NOT return upgrade review', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 0, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 1, -// num_fields_with_conflicts: 0, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).not.toMatchObject({ -// kql_query: expect.anything(), -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 0, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('non-customized w/ an upgrade (AAB diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: {}, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// }, -// deps, -// }); -// }); - -// it('returns upgrade review', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 0, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 2, -// num_fields_with_conflicts: 0, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).toMatchObject({ -// kql_query: { -// base_version: { -// saved_query_id: 'saved_query_id1', -// }, -// current_version: { -// saved_query_id: 'saved_query_id1', -// }, -// target_version: { -// saved_query_id: 'saved_query_id2', -// }, -// merged_version: { -// saved_query_id: 'saved_query_id2', -// }, -// diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, -// merge_outcome: ThreeWayMergeOutcome.Target, -// conflict: ThreeWayDiffConflict.NONE, -// has_update: true, -// has_base_version: true, -// }, -// }); -// }); - -// it('upgrades to MERGED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 0, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'MERGED', -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 0, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('customized w/o an upgrade (ABA diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// }, -// deps, -// }); -// }); - -// it('returns upgrade preview', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 0, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 1, -// num_fields_with_conflicts: 0, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).toMatchObject({ -// kql_query: { -// base_version: { -// saved_query_id: 'saved_query_id1', -// }, -// current_version: { -// saved_query_id: 'saved_query_id2', -// }, -// target_version: { -// saved_query_id: 'saved_query_id1', -// }, -// merged_version: { -// saved_query_id: 'saved_query_id2', -// }, -// diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, -// merge_outcome: ThreeWayMergeOutcome.Current, -// conflict: ThreeWayDiffConflict.NONE, -// has_update: false, -// has_base_version: true, -// }, -// }); -// }); - -// it('upgrades to MERGED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'MERGED', -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('customized w/ the matching upgrade (ABB diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// }, -// deps, -// }); -// }); - -// it('returns upgrade preview', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 0, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 1, -// num_fields_with_conflicts: 0, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).toMatchObject({ -// kql_query: { -// base_version: { -// saved_query_id: 'saved_query_id1', -// }, -// current_version: { -// saved_query_id: 'saved_query_id2', -// }, -// target_version: { -// saved_query_id: 'saved_query_id2', -// }, -// merged_version: { -// saved_query_id: 'saved_query_id2', -// }, -// diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, -// merge_outcome: ThreeWayMergeOutcome.Current, -// conflict: ThreeWayDiffConflict.NONE, -// has_update: false, -// has_base_version: true, -// }, -// }); -// }); - -// it('upgrades to MERGED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'MERGED', -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'saved_query_id2', -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id3', -// }, -// }, -// deps, -// }); -// }); - -// it('returns upgrade preview', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 1, -// num_rules_with_non_solvable_conflicts: 1, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 2, -// num_fields_with_conflicts: 1, -// num_fields_with_non_solvable_conflicts: 1, -// }); -// expect(response.rules[0].diff.fields).toMatchObject({ -// kql_query: { -// base_version: { -// saved_query_id: 'saved_query_id1', -// }, -// current_version: { -// saved_query_id: 'saved_query_id2', -// }, -// target_version: { -// saved_query_id: 'saved_query_id3', -// }, -// merged_version: { -// saved_query_id: 'saved_query_id2', -// }, -// diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, -// merge_outcome: ThreeWayMergeOutcome.Current, -// conflict: ThreeWayDiffConflict.NON_SOLVABLE, -// has_update: true, -// has_base_version: true, -// }, -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('without historical versions', () => { -// describe('customized w/ the matching upgrade (-AA diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// }, -// removeInstalledAssets: true, -// deps, -// }); -// }); - -// it('does NOT return upgrade review', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 0, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 1, -// num_fields_with_conflicts: 0, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).not.toMatchObject({ -// kql_query: expect.anything(), -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); - -// describe('customized w/ an upgrade (-AB diff case)', () => { -// beforeEach(async () => { -// await setUpRuleUpgrade({ -// assets: { -// installed: { -// type: 'saved_query', -// saved_id: 'saved_query_id1', -// }, -// patch: { -// type: 'saved_query', -// saved_id: 'saved_query_id2', -// }, -// upgrade: { -// type: 'saved_query', -// saved_id: 'saved_query_id3', -// }, -// }, -// removeInstalledAssets: true, -// deps, -// }); -// }); - -// it('returns upgrade preview', async () => { -// const response = await reviewPrebuiltRulesToUpgrade(supertest); - -// expect(response.rules).toHaveLength(1); -// expect(response.stats).toMatchObject({ -// num_rules_to_upgrade_total: 1, -// num_rules_with_conflicts: 1, -// num_rules_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff).toMatchObject({ -// num_fields_with_updates: 2, -// num_fields_with_conflicts: 1, -// num_fields_with_non_solvable_conflicts: 0, -// }); -// expect(response.rules[0].diff.fields).toMatchObject({ -// kql_query: { -// current_version: { -// saved_query_id: 'saved_query_id2', -// }, -// target_version: { -// saved_query_id: 'saved_query_id3', -// }, -// merged_version: { -// saved_query_id: 'saved_query_id3', -// }, -// diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, -// merge_outcome: ThreeWayMergeOutcome.Target, -// conflict: ThreeWayDiffConflict.SOLVABLE, -// has_update: true, -// has_base_version: false, -// }, -// }); -// }); - -// it('upgrades to RESOLVED value', async () => { -// const response = await performUpgradePrebuiltRules(es, supertest, { -// mode: ModeEnum.SPECIFIC_RULES, -// rules: [ -// { -// rule_id: DEFAULT_TEST_RULE_ID, -// revision: 1, -// version: 2, -// fields: { -// kql_query: { -// pick_version: 'RESOLVED', -// resolved_value: { -// type: KqlQueryType.saved_query, -// saved_query_id: 'resolved', -// }, -// }, -// }, -// }, -// ], -// }); - -// const upgradedRule = await securitySolutionApi.readRule({ -// query: { rule_id: DEFAULT_TEST_RULE_ID }, -// }); - -// expect(response.results.updated[0]).toMatchObject({ -// saved_id: 'resolved', -// }); -// expect(upgradedRule.body).toMatchObject({ -// saved_id: 'resolved', -// }); -// }); -// }); -// }); -// }); -// } +import { + KqlQueryType, + ThreeWayDiffOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; +import { + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; + +export function savedQueryKqlQueryField({ getService }: FtrProviderContext): void { + describe('"kql_query" with saved query', () => { + describe('non-customized w/o an upgrade (AAA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('non-customized w/ an upgrade (AAB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: {}, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { + saved_query_id: 'saved_query_id1', + }, + current: { + saved_query_id: 'saved_query_id1', + }, + target: { + saved_query_id: 'saved_query_id2', + }, + merged: { + saved_query_id: 'saved_query_id2', + }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { saved_id: 'saved_query_id2' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('customized w/o an upgrade (ABA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { + saved_query_id: 'saved_query_id1', + }, + current: { + saved_query_id: 'saved_query_id2', + }, + target: { + saved_query_id: 'saved_query_id1', + }, + merged: { + saved_query_id: 'saved_query_id2', + }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { saved_id: 'saved_query_id2' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('customized w/ the matching upgrade (ABB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { + saved_query_id: 'saved_query_id1', + }, + current: { + saved_query_id: 'saved_query_id2', + }, + target: { + saved_query_id: 'saved_query_id2', + }, + merged: { + saved_query_id: 'saved_query_id2', + }, + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedFieldsAfterUpgrade: { saved_id: 'saved_query_id2' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { + saved_query_id: 'saved_query_id1', + }, + current: { + saved_query_id: 'saved_query_id2', + }, + target: { + saved_query_id: 'saved_query_id3', + }, + merged: { + saved_query_id: 'saved_query_id2', + }, + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('without historical versions', () => { + describe('customized w/ the matching upgrade (-AA diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + + describe('customized w/ an upgrade (-AB diff case)', () => { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'saved_query', + saved_id: 'saved_query_id1', + }, + patch: { + type: 'saved_query', + saved_id: 'saved_query_id2', + }, + upgrade: { + type: 'saved_query', + saved_id: 'saved_query_id3', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { + saved_query_id: 'saved_query_id2', + }, + target: { + saved_query_id: 'saved_query_id3', + }, + merged: { + saved_query_id: 'saved_query_id3', + }, + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'kql_query', + resolvedValue: { + type: KqlQueryType.saved_query, + saved_query_id: 'resolved', + }, + expectedFieldsAfterUpgrade: { saved_id: 'resolved' }, + }, + getService + ); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts index 0913c372057d4..64c08959eb016 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/machine_learning_job_id.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function machineLearningJobIdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"machine_learning_job_id"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: {}, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - machine_learning_job_id: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: {}, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: {}, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['jobA'], + current: ['jobA'], + target: ['jobB'], + merged: ['jobB'], }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobA'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['jobB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobA'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['jobA'], + current: ['jobB'], + target: ['jobA'], + merged: ['jobB'], }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['jobB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['jobA'], + current: ['jobB'], + target: ['jobB'], + merged: ['jobB'], }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobB'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['jobB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['jobB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobC', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: ['jobA'], + current: ['jobB'], + target: ['jobC'], + merged: ['jobB'], }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - base_version: ['jobA'], - current_version: ['jobB'], - target_version: ['jobC'], - merged_version: ['jobB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - machine_learning_job_id: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'machine_learning', - machine_learning_job_id: 'jobA', - }, - patch: { - type: 'machine_learning', - machine_learning_job_id: 'jobB', - }, - upgrade: { - type: 'machine_learning', - machine_learning_job_id: 'jobC', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - machine_learning_job_id: { - current_version: ['jobB'], - target_version: ['jobC'], - merged_version: ['jobC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'machine_learning', + machine_learning_job_id: 'jobA', + }, + patch: { + type: 'machine_learning', + machine_learning_job_id: 'jobB', + }, + upgrade: { + type: 'machine_learning', + machine_learning_job_id: 'jobC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['jobB'], + target: ['jobC'], + merged: ['jobC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - machine_learning_job_id: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - machine_learning_job_id: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'machine_learning_job_id', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { machine_learning_job_id: ['resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts index 612b6d1e0e785..3af660439c1ee 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/new_terms_fields.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function newTermsFieldsField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"new_terms_fields"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: {}, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - new_terms_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: {}, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldA'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['fieldB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: {}, + upgrade: { + type: 'new_terms', new_terms_fields: ['fieldB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['fieldA'], + current: ['fieldA'], + target: ['fieldB'], + merged: ['fieldB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedFieldsAfterUpgrade: { new_terms_fields: ['fieldB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['fieldB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', new_terms_fields: ['fieldB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['fieldA'], + current: ['fieldB'], + target: ['fieldA'], + merged: ['fieldB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedFieldsAfterUpgrade: { new_terms_fields: ['fieldB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldB'], - merged_version: ['fieldB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', new_terms_fields: ['fieldB'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'new_terms', new_terms_fields: ['fieldB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['fieldA'], + current: ['fieldB'], + target: ['fieldB'], + merged: ['fieldB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedFieldsAfterUpgrade: { new_terms_fields: ['fieldB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA', 'fieldC'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - base_version: ['fieldA'], - current_version: ['fieldB'], - target_version: ['fieldA', 'fieldC'], - merged_version: ['fieldB', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: ['fieldA'], + current: ['fieldB'], + target: ['fieldA', 'fieldC'], + merged: ['fieldB', 'fieldC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - new_terms_fields: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'new_terms', - new_terms_fields: ['fieldA'], - }, - patch: { - type: 'new_terms', - new_terms_fields: ['fieldB'], - }, - upgrade: { - type: 'new_terms', - new_terms_fields: ['fieldA', 'fieldC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - new_terms_fields: { - current_version: ['fieldB'], - target_version: ['fieldA', 'fieldC'], - merged_version: ['fieldA', 'fieldC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'new_terms', + new_terms_fields: ['fieldA'], + }, + patch: { + type: 'new_terms', + new_terms_fields: ['fieldB'], + }, + upgrade: { + type: 'new_terms', + new_terms_fields: ['fieldA', 'fieldC'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['fieldB'], + target: ['fieldA', 'fieldC'], + merged: ['fieldA', 'fieldC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - new_terms_fields: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - new_terms_fields: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - new_terms_fields: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'new_terms_fields', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { new_terms_fields: ['resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts index d892b0ec40703..41c6c6f7cf2fd 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_index.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function threatIndexField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threat_index"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_index: ['indexA'], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_index: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexA'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_index: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: {}, + upgrade: { + type: 'threat_match', threat_index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: ['indexA'], + current: ['indexA'], + target: ['indexB'], + merged: ['indexB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedFieldsAfterUpgrade: { threat_index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexA'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexA'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', threat_index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexA'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: ['indexA'], + current: ['indexB'], + target: ['indexA'], + merged: ['indexB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedFieldsAfterUpgrade: { threat_index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexB'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB'], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexB'], - target_version: ['indexB'], - merged_version: ['indexB'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', threat_index: ['indexB'], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'threat_match', threat_index: ['indexB'], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: ['indexA'], + current: ['indexB'], + target: ['indexB'], + merged: ['indexB'], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedFieldsAfterUpgrade: { threat_index: ['indexB'] }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB', 'indexC'], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: true, + expectedFieldDiffValues: { + base: ['indexA'], + current: ['indexD'], + target: ['indexB', 'indexC'], + merged: ['indexD', 'indexB', 'indexC'], }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_index: { - base_version: ['indexA'], - current_version: ['indexD'], - target_version: ['indexB', 'indexC'], - merged_version: ['indexD', 'indexB', 'indexC'], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Merged, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexD'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_index: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexD'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_index: ['indexA'], - }, - patch: { - type: 'threat_match', - threat_index: ['indexD'], - }, - upgrade: { - type: 'threat_match', - threat_index: ['indexB', 'indexC'], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_index: { - current_version: ['indexD'], - target_version: ['indexB', 'indexC'], - merged_version: ['indexB', 'indexC'], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_index: ['indexA'], + }, + patch: { + type: 'threat_match', + threat_index: ['indexD'], + }, + upgrade: { + type: 'threat_match', + threat_index: ['indexB', 'indexC'], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: ['indexD'], + target: ['indexB', 'indexC'], + merged: ['indexB', 'indexC'], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_index: { - pick_version: 'RESOLVED', - resolved_value: ['resolved'], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_index: ['resolved'], - }); - expect(upgradedRule.body).toMatchObject({ - threat_index: ['resolved'], - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_index', + resolvedValue: ['resolved'], + expectedFieldsAfterUpgrade: { threat_index: ['resolved'] }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts index eef80c734dc3c..de706df8c19b1 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_indicator_path.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function threatIndicatorPathField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threat_indicator_path"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_indicator_path: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldA', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: {}, + upgrade: { + type: 'threat_match', threat_indicator_path: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: 'fieldA', + current: 'fieldA', + target: 'fieldB', + merged: 'fieldB', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldA', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', threat_indicator_path: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: 'fieldA', + current: 'fieldB', + target: 'fieldA', + merged: 'fieldB', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldB', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', threat_indicator_path: 'fieldB', - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'threat_match', threat_indicator_path: 'fieldB', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: 'fieldA', + current: 'fieldB', + target: 'fieldB', + merged: 'fieldB', + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'fieldB' }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldC', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - base_version: 'fieldA', - current_version: 'fieldB', - target_version: 'fieldC', - merged_version: 'fieldB', - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: 'fieldA', + current: 'fieldB', + target: 'fieldC', + merged: 'fieldB', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_indicator_path: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_indicator_path: 'fieldA', - }, - patch: { - type: 'threat_match', - threat_indicator_path: 'fieldB', - }, - upgrade: { - type: 'threat_match', - threat_indicator_path: 'fieldC', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_indicator_path: { - current_version: 'fieldB', - target_version: 'fieldC', - merged_version: 'fieldC', - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_indicator_path: 'fieldA', + }, + patch: { + type: 'threat_match', + threat_indicator_path: 'fieldB', + }, + upgrade: { + type: 'threat_match', + threat_indicator_path: 'fieldC', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: 'fieldB', + target: 'fieldC', + merged: 'fieldC', }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_indicator_path: { - pick_version: 'RESOLVED', - resolved_value: 'resolved', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_indicator_path: 'resolved', - }); - expect(upgradedRule.body).toMatchObject({ - threat_indicator_path: 'resolved', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_indicator_path', + resolvedValue: 'resolved', + expectedFieldsAfterUpgrade: { threat_indicator_path: 'resolved' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts index 44670bd9f7acf..06763e06db802 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_mapping.ts @@ -5,741 +5,369 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function threatMappingField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threat_mapping"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + target: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedFieldsAfterUpgrade: { + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_mapping: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + merged: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedFieldsAfterUpgrade: { + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - expect(upgradedRule.body).toMatchObject({ + }, + upgrade: { + type: 'threat_match', threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + merged: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedFieldsAfterUpgrade: { + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, - ], - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - base_version: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], - current_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - target_version: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], - merged_version: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + current: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_mapping: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }, - ], - }, - patch: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - }, - upgrade: { - type: 'threat_match', - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, - ], - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_mapping: { - current_version: [ - { entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }, - ], - target_version: [ - { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, - ], - merged_version: [ - { entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }, - ], - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldA', value: 'fieldZ' }] }], + }, + patch: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + }, + upgrade: { + type: 'threat_match', + threat_mapping: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: [{ entries: [{ type: 'mapping', field: 'fieldB', value: 'fieldZ' }] }], + target: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], + merged: [{ entries: [{ type: 'mapping', field: 'fieldC', value: 'fieldZ' }] }], }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_mapping: { - pick_version: 'RESOLVED', - resolved_value: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_mapping: [ - { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, - ], - }); - expect(upgradedRule.body).toMatchObject({ - threat_mapping: [ + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_mapping', + resolvedValue: [ { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, ], - }); - }); + expectedFieldsAfterUpgrade: { + threat_mapping: [ + { entries: [{ type: 'mapping', field: 'resolvedA', value: 'resolvedB' }] }, + ], + }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts index 1e2957860d22f..a30c3a4cb6cf9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threat_query.ts @@ -5,806 +5,463 @@ * 2.0. */ -import expect from 'expect'; import { KqlQueryType, - ModeEnum, - ThreeWayDiffConflict, ThreeWayDiffOutcome, - ThreeWayMergeOutcome, } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function threatQueryField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threat_query"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: {}, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: {}, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - current_version: { + current: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - target_version: { + target: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - merged_version: { + merged: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedFieldsAfterUpgrade: { + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - current_version: { + current: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - target_version: { + target: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - merged_version: { + merged: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedFieldsAfterUpgrade: { + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - current_version: { + current: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - target_version: { + target: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - merged_version: { + merged: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'process.name:*.sys', - threat_language: 'kuery', - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedFieldsAfterUpgrade: { + threat_query: 'process.name:*.sys', + threat_language: 'kuery', + }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.com', - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_query: { - base_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { type: KqlQueryType.inline_query, query: 'process.name:*.exe', language: 'kuery', filters: [], }, - current_version: { + current: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - target_version: { + target: { type: KqlQueryType.inline_query, query: 'process.name:*.com', language: 'kuery', filters: [], }, - merged_version: { + merged: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threat_query: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threat_match', - threat_query: 'process.name:*.exe', - }, - patch: { - type: 'threat_match', - threat_query: 'process.name:*.sys', - }, - upgrade: { - type: 'threat_match', - threat_query: 'process.name:*.com', - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threat_query: { - current_version: { + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threat_match', + threat_query: 'process.name:*.exe', + }, + patch: { + type: 'threat_match', + threat_query: 'process.name:*.sys', + }, + upgrade: { + type: 'threat_match', + threat_query: 'process.name:*.com', + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { type: KqlQueryType.inline_query, query: 'process.name:*.sys', language: 'kuery', filters: [], }, - target_version: { + target: { type: KqlQueryType.inline_query, query: 'process.name:*.com', language: 'kuery', filters: [], }, - merged_version: { + merged: { type: KqlQueryType.inline_query, query: 'process.name:*.com', language: 'kuery', filters: [], }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threat_query: { - pick_version: 'RESOLVED', - resolved_value: { - type: KqlQueryType.inline_query, - query: 'resolved:*', - language: 'kuery', - filters: [], - }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - expect(upgradedRule.body).toMatchObject({ - threat_query: 'resolved:*', - threat_language: 'kuery', - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threat_query', + resolvedValue: { + type: KqlQueryType.inline_query, + query: 'resolved:*', + language: 'kuery', + filters: [], + }, + expectedFieldsAfterUpgrade: { threat_query: 'resolved:*', threat_language: 'kuery' }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts index 37d54b7aeed2a..9469fda5f8ae6 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/diffable_rule_fields/type_specific_fields/threshold.ts @@ -5,655 +5,321 @@ * 2.0. */ -import expect from 'expect'; -import { - ModeEnum, - ThreeWayDiffConflict, - ThreeWayDiffOutcome, - ThreeWayMergeOutcome, -} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { ThreeWayDiffOutcome } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { FtrProviderContext } from '../../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, reviewPrebuiltRulesToUpgrade } from '../../../../../../utils'; +import type { TestFieldRuleUpgradeAssets } from '../test_helpers'; import { - DEFAULT_TEST_RULE_ID, - setUpRuleUpgrade, -} from '../../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; + testFieldUpgradeReview, + testFieldUpgradesToMergedValue, + testFieldUpgradesToResolvedValue, +} from '../test_helpers'; export function thresholdField({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - - const deps = { - es, - supertest, - log, - }; - describe('"threshold"', () => { describe('non-customized w/o an upgrade (AAA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: {}, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - }, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threshold: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('non-customized w/ an upgrade (AAB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: {}, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: {}, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.StockValueCanUpdate, + expectedFieldDiffValues: { + base: { value: 10, field: ['fieldA'] }, + current: { value: 10, field: ['fieldA'] }, + target: { value: 10, field: ['fieldB'] }, + merged: { value: 10, field: ['fieldB'] }, }, - deps, - }); - }); - - it('returns upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldA'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.NONE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 0, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedFieldsAfterUpgrade: { threshold: { value: 10, field: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('customized w/o an upgrade (ABA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldA'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + expectedFieldDiffValues: { + base: { value: 10, field: ['fieldA'] }, + current: { value: 10, field: ['fieldB'] }, + target: { value: 10, field: ['fieldA'] }, + merged: { value: 10, field: ['fieldB'] }, }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedFieldsAfterUpgrade: { threshold: { value: 10, field: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ the matching upgrade (ABB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + expectedFieldDiffValues: { + base: { value: 10, field: ['fieldA'] }, + current: { value: 10, field: ['fieldB'] }, + target: { value: 10, field: ['fieldB'] }, + merged: { value: 10, field: ['fieldB'] }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldB'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NONE, - has_update: false, - has_base_version: true, - }, - }); - }); - - it('upgrades to MERGED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'MERGED', - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 10, field: ['fieldB'] }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToMergedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedFieldsAfterUpgrade: { threshold: { value: 10, field: ['fieldB'] } }, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ an upgrade resulting in a conflict (ABC diff case, non-solvable conflict)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldC' }, - }, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + isSolvableConflict: false, + expectedFieldDiffValues: { + base: { value: 10, field: ['fieldA'] }, + current: { value: 10, field: ['fieldB'] }, + target: { value: 10, field: ['fieldC'] }, + merged: { value: 10, field: ['fieldB'] }, }, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 1, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threshold: { - base_version: { value: 10, field: ['fieldA'] }, - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldC'] }, - merged_version: { value: 10, field: ['fieldB'] }, - diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Current, - conflict: ThreeWayDiffConflict.NON_SOLVABLE, - has_update: true, - has_base_version: true, - }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('without historical versions', () => { describe('customized w/ the matching upgrade (-AA diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('does NOT return upgrade review', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 1, - num_fields_with_conflicts: 0, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).not.toMatchObject({ - threshold: expect.anything(), - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseNoUpdate, + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); describe('customized w/ an upgrade (-AB diff case)', () => { - beforeEach(async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'threshold', - threshold: { value: 10, field: 'fieldA' }, - }, - patch: { - type: 'threshold', - threshold: { value: 10, field: 'fieldB' }, - }, - upgrade: { - type: 'threshold', - threshold: { value: 10, field: 'fieldC' }, - }, - }, - removeInstalledAssets: true, - deps, - }); - }); - - it('returns upgrade preview', async () => { - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules).toHaveLength(1); - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 1, - num_rules_with_conflicts: 1, - num_rules_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 2, - num_fields_with_conflicts: 1, - num_fields_with_non_solvable_conflicts: 0, - }); - expect(response.rules[0].diff.fields).toMatchObject({ - threshold: { - current_version: { value: 10, field: ['fieldB'] }, - target_version: { value: 10, field: ['fieldC'] }, - merged_version: { value: 10, field: ['fieldC'] }, - diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, - merge_outcome: ThreeWayMergeOutcome.Target, - conflict: ThreeWayDiffConflict.SOLVABLE, - has_update: true, - has_base_version: false, + const ruleUpgradeAssets: TestFieldRuleUpgradeAssets = { + installed: { + type: 'threshold', + threshold: { value: 10, field: 'fieldA' }, + }, + patch: { + type: 'threshold', + threshold: { value: 10, field: 'fieldB' }, + }, + upgrade: { + type: 'threshold', + threshold: { value: 10, field: 'fieldC' }, + }, + removeInstalledAssets: true, + }; + + testFieldUpgradeReview( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + expectedDiffOutcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + expectedFieldDiffValues: { + current: { value: 10, field: ['fieldB'] }, + target: { value: 10, field: ['fieldC'] }, + merged: { value: 10, field: ['fieldC'] }, }, - }); - }); - - it('upgrades to RESOLVED value', async () => { - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: DEFAULT_TEST_RULE_ID, - revision: 1, - version: 2, - fields: { - threshold: { - pick_version: 'RESOLVED', - resolved_value: { value: 50, field: 'resolved' }, - }, - }, - }, - ], - }); - - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: DEFAULT_TEST_RULE_ID }, - }); - - expect(response.results.updated[0]).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - expect(upgradedRule.body).toMatchObject({ - threshold: { value: 50, field: ['resolved'] }, - }); - }); + }, + getService + ); + + testFieldUpgradesToResolvedValue( + { + ruleUpgradeAssets, + diffableRuleFieldName: 'threshold', + resolvedValue: { value: 50, field: 'resolved' }, + expectedFieldsAfterUpgrade: { threshold: { value: 50, field: ['resolved'] } }, + }, + getService + ); }); }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts index a7566eb8229af..6ba8f178124ac 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts @@ -163,6 +163,7 @@ export default ({ getService }: FtrProviderContext): void => { it('returns num of rules with non-solvable conflicts', async () => { await setUpRuleUpgrade({ assets: [ + // Name field has a non-solvable upgrade conflict { installed: { rule_id: 'query-rule', @@ -181,6 +182,7 @@ export default ({ getService }: FtrProviderContext): void => { version: 2, }, }, + // tags field values are merged resulting in a solvable upgrade conflict { installed: { rule_id: 'saved-query-rule', diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/review_upgrade_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/review_upgrade_prebuilt_rules.ts index 17347ffcdd1e3..860d9951457a8 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/review_upgrade_prebuilt_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/review_upgrade_prebuilt_rules.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { PartialRuleDiff } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { REVIEW_RULE_UPGRADE_URL } from '@kbn/security-solution-plugin/common/api/detection_engine/prebuilt_rules/urls'; import { ReviewRuleUpgradeResponseBody } from '@kbn/security-solution-plugin/common/api/detection_engine/prebuilt_rules/review_rule_upgrade/review_rule_upgrade_route'; import type SuperTest from 'supertest'; @@ -28,3 +29,11 @@ export const reviewPrebuiltRulesToUpgrade = async ( return response.body; }; + +export async function fetchFirstPrebuiltRuleUpgradeReviewDiff( + supertest: SuperTest.Agent +): Promise { + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + return response.rules[0].diff; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts index 966c34352fdc0..78a11f0ed7180 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/set_up_rule_upgrade.ts @@ -26,7 +26,7 @@ interface SetUpRuleUpgradeDeps { type PartialPrebuiltRuleAsset = Pick & Partial; -interface RuleUpgradeAssets { +export interface RuleUpgradeAssets { installed: PartialPrebuiltRuleAsset; patch: Partial; upgrade: PartialPrebuiltRuleAsset; @@ -39,6 +39,8 @@ interface SetUpRuleUpgradeParams { } export const DEFAULT_TEST_RULE_ID = 'test-rule'; +export const DEFAULT_INSTALLED_RULE_VERSION = 1; +export const DEFAULT_RULE_UPDATE_VERSION = 2; export async function setUpRuleUpgrade({ assets, @@ -51,7 +53,7 @@ export async function setUpRuleUpgrade({ await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(ruleAssets.installed.type, { rule_id: DEFAULT_TEST_RULE_ID, - version: 1, + version: DEFAULT_INSTALLED_RULE_VERSION, ...ruleAssets.installed, }), ]); @@ -76,7 +78,7 @@ export async function setUpRuleUpgrade({ await createHistoricalPrebuiltRuleAssetSavedObjects(deps.es, [ createRuleAssetSavedObjectOfType(ruleAssets.upgrade.type, { rule_id: DEFAULT_TEST_RULE_ID, - version: 2, + version: DEFAULT_RULE_UPDATE_VERSION, ...ruleAssets.upgrade, }), ]); From 651d2a3ca82eb76f9d3fa1d6ec7b5434608a97a1 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sun, 16 Feb 2025 13:30:34 +0100 Subject: [PATCH 18/20] refactor rule upgrade tests --- .../upgrade_one_prebuilt_rule.ts | 368 ----------------- .../upgrade_single_prebuilt_rule.ts | 388 ++++++++++++++++++ 2 files changed, 388 insertions(+), 368 deletions(-) delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_single_prebuilt_rule.ts diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts deleted file mode 100644 index 55ebc258d362f..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_one_prebuilt_rule.ts +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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 expect from 'expect'; -import type SuperTest from 'supertest'; -import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { setUpRuleUpgrade } from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; -import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; -import { performUpgradePrebuiltRules, getWebHookAction } from '../../../../../utils'; - -export function upgradeOnePrebuiltRule({ getService }: FtrProviderContext): void { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - const securitySolutionApi = getService('securitySolutionApi'); - const deps = { - es, - supertest, - log, - }; - - describe('one rule with historical versions', () => { - const RULE_TYPES = [ - 'query', - 'saved_query', - 'eql', - 'esql', - 'threat_match', - 'threshold', - 'machine_learning', - 'new_terms', - ] as const; - - for (const ruleType of RULE_TYPES) { - it(`upgrades non-customized ${ruleType} rule`, async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - name: 'Initial name', - rule_id: 'rule_1', - version: 1, - }, - patch: {}, - upgrade: { - type: ruleType, - name: 'Updated name', - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 0, - version: 2, - pick_version: 'TARGET', - }, - ], - }); - - expect(response.results.updated).toMatchObject([ - { - rule_id: 'rule_1', - version: 2, - name: 'Updated name', - }, - ]); - }); - - it(`upgrades customized ${ruleType} rule`, async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleType, - name: 'Initial name', - rule_id: 'rule_1', - version: 1, - }, - patch: { - rule_id: 'rule_1', - name: 'Customized name', - }, - upgrade: { - type: ruleType, - name: 'Updated name', - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 1, - version: 2, - pick_version: 'TARGET', - }, - ], - }); - - expect(response.results.updated).toMatchObject([ - { - rule_id: 'rule_1', - version: 2, - name: 'Updated name', - }, - ]); - }); - } - - const RULE_TYPE_CHANGES = RULE_TYPES.flatMap((ruleTypeA) => - RULE_TYPES.map((ruleTypeB) => [ruleTypeA, ruleTypeB] as const) - ).filter(([ruleTypeA, ruleTypeB]) => ruleTypeA !== ruleTypeB); - - for (const [ruleTypeA, ruleTypeB] of RULE_TYPE_CHANGES) { - it(`upgrades non-customized ${ruleTypeA} rule to ${ruleTypeB} rule`, async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleTypeA, - name: 'Initial name', - rule_id: 'rule_1', - version: 1, - }, - patch: {}, - upgrade: { - type: ruleTypeB, - name: 'Updated name', - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 0, - version: 2, - pick_version: 'TARGET', - }, - ], - }); - - expect(response.results.updated).toMatchObject([ - { - rule_id: 'rule_1', - version: 2, - type: ruleTypeB, - name: 'Updated name', - }, - ]); - }); - - it(`upgrades customized ${ruleTypeA} rule to ${ruleTypeB} rule type`, async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: ruleTypeA, - name: 'Initial name', - rule_id: 'rule_1', - version: 1, - }, - patch: { - rule_id: 'rule_1', - name: 'Customized name', - }, - upgrade: { - type: ruleTypeB, - name: 'Updated name', - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 1, - version: 2, - pick_version: 'TARGET', - }, - ], - }); - - expect(response.results.updated).toMatchObject([ - { - rule_id: 'rule_1', - version: 2, - type: ruleTypeB, - name: 'Updated name', - }, - ]); - }); - } - - for (const pickVersion of ['BASE', 'CURRENT', 'MERGED'] as const) { - it(`UNABLE to upgrade rule when rule type changed and is ${pickVersion}`, async () => { - await setUpRuleUpgrade({ - assets: { - installed: { - type: 'query', - name: 'Initial name', - rule_id: 'rule_1', - version: 1, - }, - patch: { - rule_id: 'rule_1', - name: 'Customized name', - }, - upgrade: { - type: 'saved_query', - name: 'Updated name', - rule_id: 'rule_1', - version: 2, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.SPECIFIC_RULES, - rules: [ - { - rule_id: 'rule_1', - revision: 1, - version: 2, - pick_version: pickVersion, - }, - ], - }); - - expect(response.summary).toMatchObject({ - total: 1, - succeeded: 0, - skipped: 0, - failed: 1, - }); - expect(response.errors).toHaveLength(1); - }); - } - - for (const ruleType of RULE_TYPES) { - it(`UNABLE to upgrade non-upgradable fields for ${ruleType} rule`, async () => { - const NON_UPGRADABLE_FIELDS = { - enabled: true, - exceptions_list: [ - { - id: 'test-list', - list_id: 'test-list', - type: 'detection', - namespace_type: 'single', - } as const, - ], - actions: [await createAction(supertest)], - response_actions: [ - { - params: { - command: 'isolate' as const, - comment: 'comment', - }, - action_type_id: '.endpoint' as const, - }, - ], - meta: { some_key: 'some_value' }, - output_index: '.siem-signals-default', - namespace: 'default', - ...(ruleType === 'threat_match' ? { concurrent_searches: 5, items_per_search: 100 } : {}), - }; - - await setUpRuleUpgrade({ - assets: { - installed: { - rule_id: 'rule_1', - version: 1, - type: ruleType, - }, - patch: { - rule_id: 'rule_1', - type: ruleType, - ...NON_UPGRADABLE_FIELDS, - // Patch for Threshold rules fails without threshold specified - ...(ruleType === 'threshold' ? { threshold: { value: 10, field: 'fieldA' } } : {}), - }, - upgrade: { - rule_id: 'rule_1', - version: 2, - type: ruleType, - }, - }, - deps, - }); - - const response = await performUpgradePrebuiltRules(es, supertest, { - mode: ModeEnum.ALL_RULES, - pick_version: 'TARGET', - }); - const upgradedRule = await securitySolutionApi.readRule({ - query: { rule_id: 'rule_1' }, - }); - - expect(response.results.updated).toMatchObject([ - { - ...NON_UPGRADABLE_FIELDS, - version: 2, - }, - ]); - expect(upgradedRule.body).toMatchObject({ - ...NON_UPGRADABLE_FIELDS, - version: 2, - }); - }); - } - }); -} - -async function createAction(supertest: SuperTest.Agent) { - const createConnector = async (payload: Record) => - ( - await supertest - .post('/api/actions/connector') - .set('kbn-xsrf', 'true') - .send(payload) - .expect(200) - ).body; - - const createWebHookConnector = () => createConnector(getWebHookAction()); - - const webHookAction = await createWebHookConnector(); - - const defaultRuleAction = { - id: webHookAction.id, - action_type_id: '.webhook' as const, - group: 'default' as const, - params: { - body: '{"test":"a default action"}', - }, - frequency: { - notifyWhen: 'onThrottleInterval' as const, - summary: true, - throttle: '1h' as const, - }, - uuid: 'd487ec3d-05f2-44ad-8a68-11c97dc92202', - }; - - return defaultRuleAction; -} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_single_prebuilt_rule.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_single_prebuilt_rule.ts new file mode 100644 index 0000000000000..6f345365a4e2b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/upgrade_single_prebuilt_rule.ts @@ -0,0 +1,388 @@ +/* + * 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 expect from 'expect'; +import type SuperTest from 'supertest'; +import { ModeEnum } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { + DEFAULT_TEST_RULE_ID, + setUpRuleUpgrade, +} from '../../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; +import { FtrProviderContext } from '../../../../../../../ftr_provider_context'; +import { performUpgradePrebuiltRules, getWebHookAction } from '../../../../../utils'; + +export function upgradeSinglePrebuiltRule({ getService }: FtrProviderContext): void { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + const securitySolutionApi = getService('securitySolutionApi'); + const deps = { + es, + supertest, + log, + }; + + const RULE_TYPES = [ + 'query', + 'saved_query', + 'eql', + 'esql', + 'threat_match', + 'threshold', + 'machine_learning', + 'new_terms', + ] as const; + + describe('single rule', () => { + for (const withHistoricalVersions of [true, false]) { + describe( + withHistoricalVersions ? 'with historical versions' : 'without historical versions', + () => { + for (const ruleType of RULE_TYPES) { + it(`upgrades non-customized ${ruleType} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + name: 'Initial name', + version: 1, + }, + patch: {}, + upgrade: { + type: ruleType, + name: 'Updated name', + version: 2, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + const expected = { + rule_id: DEFAULT_TEST_RULE_ID, + version: 2, + name: 'Updated name', + }; + + expect(response.results.updated).toMatchObject([expected]); + expect(upgradedRule.body).toMatchObject(expected); + }); + + it(`upgrades customized ${ruleType} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleType, + name: 'Initial name', + version: 1, + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: ruleType, + name: 'Updated name', + version: 2, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + const expected = { + rule_id: DEFAULT_TEST_RULE_ID, + version: 2, + name: 'Updated name', + }; + + expect(response.results.updated).toMatchObject([expected]); + expect(upgradedRule.body).toMatchObject(expected); + }); + } + + const RULE_TYPE_CHANGES = RULE_TYPES.flatMap((ruleTypeA) => + RULE_TYPES.map((ruleTypeB) => [ruleTypeA, ruleTypeB] as const) + ).filter(([ruleTypeA, ruleTypeB]) => ruleTypeA !== ruleTypeB); + + for (const [ruleTypeA, ruleTypeB] of RULE_TYPE_CHANGES) { + it(`upgrades non-customized ${ruleTypeA} rule to ${ruleTypeB} rule`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleTypeA, + name: 'Initial name', + version: 1, + }, + patch: {}, + upgrade: { + type: ruleTypeB, + name: 'Updated name', + version: 2, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 0, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + const expected = { + rule_id: DEFAULT_TEST_RULE_ID, + version: 2, + type: ruleTypeB, + name: 'Updated name', + }; + + expect(response.results.updated).toMatchObject([expected]); + expect(upgradedRule.body).toMatchObject(expected); + }); + + it(`upgrades customized ${ruleTypeA} rule to ${ruleTypeB} rule type`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: ruleTypeA, + name: 'Initial name', + version: 1, + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: ruleTypeB, + name: 'Updated name', + version: 2, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + pick_version: 'TARGET', + }, + ], + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + const expected = { + rule_id: DEFAULT_TEST_RULE_ID, + version: 2, + type: ruleTypeB, + name: 'Updated name', + }; + + expect(response.results.updated).toMatchObject([expected]); + expect(upgradedRule.body).toMatchObject(expected); + }); + } + + for (const pickVersion of ['BASE', 'CURRENT', 'MERGED'] as const) { + it(`UNABLE to upgrade rule when rule type changed and is ${pickVersion}`, async () => { + await setUpRuleUpgrade({ + assets: { + installed: { + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + name: 'Customized name', + }, + upgrade: { + type: 'saved_query', + name: 'Updated name', + version: 2, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.SPECIFIC_RULES, + rules: [ + { + rule_id: DEFAULT_TEST_RULE_ID, + revision: 1, + version: 2, + pick_version: pickVersion, + }, + ], + }); + + expect(response.summary).toMatchObject({ + total: 1, + succeeded: 0, + skipped: 0, + failed: 1, + }); + expect(response.errors).toHaveLength(1); + }); + } + + for (const ruleType of RULE_TYPES) { + it(`UNABLE to upgrade non-upgradable fields for ${ruleType} rule`, async () => { + const NON_UPGRADABLE_FIELDS = { + enabled: true, + exceptions_list: [ + { + id: 'test-list', + list_id: 'test-list', + type: 'detection', + namespace_type: 'single', + } as const, + ], + actions: [await createAction(supertest)], + response_actions: [ + { + params: { + command: 'isolate' as const, + comment: 'comment', + }, + action_type_id: '.endpoint' as const, + }, + ], + meta: { some_key: 'some_value' }, + output_index: '.siem-signals-default', + namespace: 'default', + ...(ruleType === 'threat_match' + ? { concurrent_searches: 5, items_per_search: 100 } + : {}), + }; + + await setUpRuleUpgrade({ + assets: { + installed: { + version: 1, + type: ruleType, + }, + patch: { + type: ruleType, + ...NON_UPGRADABLE_FIELDS, + // Patch for Threshold rules fails without threshold specified + ...(ruleType === 'threshold' + ? { threshold: { value: 10, field: 'fieldA' } } + : {}), + }, + upgrade: { + version: 2, + type: ruleType, + }, + }, + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await performUpgradePrebuiltRules(es, supertest, { + mode: ModeEnum.ALL_RULES, + pick_version: 'TARGET', + }); + const upgradedRule = await securitySolutionApi.readRule({ + query: { rule_id: DEFAULT_TEST_RULE_ID }, + }); + + expect(response.results.updated).toMatchObject([ + { + ...NON_UPGRADABLE_FIELDS, + version: 2, + }, + ]); + expect(upgradedRule.body).toMatchObject({ + ...NON_UPGRADABLE_FIELDS, + version: 2, + }); + }); + } + } + ); + } + }); +} + +async function createAction(supertest: SuperTest.Agent) { + const createConnector = async (payload: Record) => + ( + await supertest + .post('/api/actions/connector') + .set('kbn-xsrf', 'true') + .send(payload) + .expect(200) + ).body; + + const createWebHookConnector = () => createConnector(getWebHookAction()); + + const webHookAction = await createWebHookConnector(); + + const defaultRuleAction = { + id: webHookAction.id, + action_type_id: '.webhook' as const, + group: 'default' as const, + params: { + body: '{"test":"a default action"}', + }, + frequency: { + notifyWhen: 'onThrottleInterval' as const, + summary: true, + throttle: '1h' as const, + }, + uuid: 'd487ec3d-05f2-44ad-8a68-11c97dc92202', + }; + + return defaultRuleAction; +} From 5b4e589e670bdb77f3d2eac8ca0268c4a657d267 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sun, 16 Feb 2025 13:31:08 +0100 Subject: [PATCH 19/20] refactor rule upgrade review tests --- .../preview_prebuilt_rules_upgrade.ts | 866 ++++++++++-------- 1 file changed, 497 insertions(+), 369 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts index 6ba8f178124ac..9d80d14257c37 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/preview_prebuilt_rules_upgrade.ts @@ -8,7 +8,11 @@ import expect from 'expect'; import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { deleteAllPrebuiltRuleAssets, reviewPrebuiltRulesToUpgrade } from '../../../../utils'; +import { + deleteAllPrebuiltRuleAssets, + fetchFirstPrebuiltRuleUpgradeReviewDiff, + reviewPrebuiltRulesToUpgrade, +} from '../../../../utils'; import { setUpRuleUpgrade } from '../../../../utils/rules/prebuilt_rules/set_up_rule_upgrade'; export default ({ getService }: FtrProviderContext): void => { @@ -28,375 +32,499 @@ export default ({ getService }: FtrProviderContext): void => { await deleteAllPrebuiltRuleAssets(es, log); }); - describe('stats', () => { - it('returns num of rules with upgrades', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'query-rule', - type: 'query', - version: 2, - }, - }, - { - installed: { - rule_id: 'saved-query-rule', - type: 'query', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'saved-query-rule', - type: 'query', - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_to_upgrade_total: 2, - }); - }); - - it('returns zero conflicts when there are no conflicts', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'query-rule', - type: 'query', - version: 2, - }, - }, - { - installed: { - rule_id: 'saved-query-rule', - type: 'query', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'saved-query-rule', - type: 'query', - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_with_conflicts: 0, - num_rules_with_non_solvable_conflicts: 0, - }); - }); - - it('returns num of rules with conflicts', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - version: 2, - }, - }, - { - installed: { - rule_id: 'saved-query-rule', - type: 'query', - tags: ['tagA'], - version: 1, - }, - patch: { - rule_id: 'saved-query-rule', - tags: ['tagB'], - }, - upgrade: { - rule_id: 'saved-query-rule', - type: 'query', - tags: ['tagC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_with_conflicts: 2, - }); - }); - - it('returns num of rules with non-solvable conflicts', async () => { - await setUpRuleUpgrade({ - assets: [ - // Name field has a non-solvable upgrade conflict - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - version: 2, - }, - }, - // tags field values are merged resulting in a solvable upgrade conflict - { - installed: { - rule_id: 'saved-query-rule', - type: 'query', - tags: ['tagA'], - version: 1, - }, - patch: { - rule_id: 'saved-query-rule', - tags: ['tagB'], - }, - upgrade: { - rule_id: 'saved-query-rule', - type: 'query', - tags: ['tagC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_with_non_solvable_conflicts: 1, - }); - }); - - it('returns num of rules with conflicts when historical versions are missing', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'query-rule', - type: 'query', - version: 2, - }, - }, - { - installed: { - rule_id: 'saved-query-rule', - type: 'query', - version: 1, - }, - patch: {}, - upgrade: { - rule_id: 'saved-query-rule', - type: 'query', - name: 'Updated name', - version: 2, - }, - }, - ], - removeInstalledAssets: true, - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.stats).toMatchObject({ - num_rules_with_conflicts: 2, - }); - }); - }); + for (const withHistoricalVersions of [true, false]) { + describe( + withHistoricalVersions ? 'with historical versions' : 'without historical versions', + () => { + describe('stats', () => { + it('returns num of rules with upgrades', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); - describe('fields diff stats', () => { - it('returns num of fields with updates', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - tags: ['tabA'], - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - tags: ['tabC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_updates: 3, // name + tags + version = 3 fields - }); - }); - - it('returns num of fields with conflicts', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - tags: ['tabA'], - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - tags: ['tabB'], - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - tags: ['tabC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_conflicts: 2, - }); - }); - - it('returns num of fields with non-solvable conflicts', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - tags: ['tabA'], - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - tags: ['tabB'], - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - tags: ['tabC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules[0].diff).toMatchObject({ - num_fields_with_non_solvable_conflicts: 1, - }); - }); - }); + const response = await reviewPrebuiltRulesToUpgrade(supertest); - describe('fields diff', () => { - it('returns fields diff', async () => { - await setUpRuleUpgrade({ - assets: [ - { - installed: { - rule_id: 'query-rule', - type: 'query', - name: 'Initial name', - tags: ['tabA'], - version: 1, - }, - patch: { - rule_id: 'query-rule', - name: 'Customized name', - }, - upgrade: { - rule_id: 'query-rule', - type: 'query', - name: 'Updated name', - tags: ['tabC'], - version: 2, - }, - }, - ], - deps, - }); - - const response = await reviewPrebuiltRulesToUpgrade(supertest); - - expect(response.rules[0].diff.fields).toMatchObject({ - name: expect.any(Object), - tags: expect.any(Object), - }); - }); - }); + expect(response.stats).toMatchObject({ + num_rules_to_upgrade_total: 2, + }); + }); + + it('returns zero conflicts when there are no conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 0, + num_rules_with_non_solvable_conflicts: 0, + }); + }); + + it('returns num of rules with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + + it('returns num of rules with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + // Name field has a non-solvable upgrade conflict + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + // tags field values are merged resulting in a solvable upgrade conflict + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagA'], + version: 1, + }, + patch: { + rule_id: 'saved-query-rule', + tags: ['tagB'], + }, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + tags: ['tagC'], + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + // Missing rule's base version doesn't allow to detect non solvable conflicts + num_rules_with_non_solvable_conflicts: withHistoricalVersions ? 1 : 0, + }); + }); + + if (!withHistoricalVersions) { + it('returns num of rules with conflicts caused by missing historical versions', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'query-rule', + type: 'query', + version: 2, + }, + }, + { + installed: { + rule_id: 'saved-query-rule', + type: 'query', + version: 1, + }, + patch: {}, + upgrade: { + rule_id: 'saved-query-rule', + type: 'query', + name: 'Updated name', + version: 2, + }, + }, + ], + removeInstalledAssets: true, + deps, + }); + + const response = await reviewPrebuiltRulesToUpgrade(supertest); + + expect(response.stats).toMatchObject({ + num_rules_with_conflicts: 2, + }); + }); + } + }); + + describe('fields diff stats', () => { + it('returns num of fields with updates', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff).toMatchObject({ + num_fields_with_updates: 3, // name + tags + version = 3 fields + }); + }); + + it('returns num of fields with conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff).toMatchObject({ + num_fields_with_conflicts: 2, + }); + }); + + it('returns num of fields with non-solvable conflicts', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + tags: ['tabB'], + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + tags: ['tabC'], + version: 2, + }, + }, + ], + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff).toMatchObject({ + num_fields_with_non_solvable_conflicts: 1, + }); + }); + }); + + describe('fields diff', () => { + it('returns fields diff for fields with upgrades', async () => { + await setUpRuleUpgrade({ + assets: [ + // description - non-customized + // name - customized + // tags - customized + { + installed: { + rule_id: 'query-rule', + type: 'query', + name: 'Initial name', + description: 'Initial description', + tags: ['tabA'], + version: 1, + }, + patch: { + rule_id: 'query-rule', + name: 'Customized name', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + name: 'Updated name', + description: 'Updated description', + tags: ['tabC'], + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff.fields).toMatchObject({ + name: { + has_update: true, + }, + description: { + has_update: true, + }, + tags: { + has_update: true, + }, + }); + }); + + it(`asserts "has_update" is ${!withHistoricalVersions} for customized fields w/o upgrades`, async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + index: ['indexA'], + interval: '5m', + from: 'now-20m', + to: 'now', + version: 1, + }, + patch: { + rule_id: 'query-rule', + alert_suppression: { group_by: ['fieldB'] }, + index: ['indexB'], + interval: '3m', + from: 'now-10m', + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + alert_suppression: { group_by: ['fieldA'] }, + index: ['indexA'], + interval: '5m', + from: 'now-20m', + to: 'now', + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff.fields).toMatchObject({ + alert_suppression: { + has_update: !withHistoricalVersions, + }, + data_source: { + has_update: !withHistoricalVersions, + }, + rule_schedule: { + has_update: !withHistoricalVersions, + }, + }); + }); + + it('asserts returned fields diff have base version', async () => { + await setUpRuleUpgrade({ + assets: [ + { + installed: { + rule_id: 'query-rule', + type: 'query', + note: 'Initial note', + max_signals: 100, + risk_score: 10, + }, + patch: { + rule_id: 'query-rule', + max_signals: 150, + risk_score: 20, + }, + upgrade: { + rule_id: 'query-rule', + type: 'query', + note: 'Updated note', + max_signals: 100, + risk_score: 30, + version: 2, + }, + }, + ], + removeInstalledAssets: !withHistoricalVersions, + deps, + }); + + const fieldsDiff = await fetchFirstPrebuiltRuleUpgradeReviewDiff(supertest); + + expect(fieldsDiff.fields).toMatchObject({ + note: { + has_base_version: withHistoricalVersions, + }, + max_signals: { + has_base_version: withHistoricalVersions, + }, + risk_score: { + has_base_version: withHistoricalVersions, + }, + }); + }); + }); + } + ); + } }); }; From de998e52a43adf09c16324e8402b27d4ca683bb7 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Sun, 16 Feb 2025 14:47:58 +0100 Subject: [PATCH 20/20] fix import --- .../customization_enabled/upgrade_prebuilt_rules/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts index 0e9cbef2e1468..03b0c28326f4b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/prebuilt_rule_customization/customization_enabled/upgrade_prebuilt_rules/index.ts @@ -10,7 +10,7 @@ import { deleteAllPrebuiltRuleAssets } from '../../../../../utils'; import { deleteAllRules } from '../../../../../../../../common/utils/security_solution'; import { bulkUpgradeAllPrebuiltRules } from './bulk_upgrade_all_prebuilt_rules'; import { bulkUpgradeSelectedPrebuiltRules } from './bulk_upgrade_selected_prebuilt_rules'; -import { upgradeOnePrebuiltRule } from './upgrade_one_prebuilt_rule'; +import { upgradeSinglePrebuiltRule } from './upgrade_single_prebuilt_rule'; export default (context: FtrProviderContext): void => { const es = context.getService('es'); @@ -25,6 +25,6 @@ export default (context: FtrProviderContext): void => { bulkUpgradeAllPrebuiltRules(context); bulkUpgradeSelectedPrebuiltRules(context); - upgradeOnePrebuiltRule(context); + upgradeSinglePrebuiltRule(context); }); };