GetCampaignLowSimilarityIncidentsInfo
Gets the campaign incidents with low similarity information as a markdown table. This automation runs using the default Limited User role, unless you explicitly change the permissions. For more information, see the section about permissions here: - For Cortex XSOAR 6 see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations - For Cortex XSOAR 8 Cloud see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script - For Cortex XSOAR 8.7 On-prem see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script
python · Phishing Campaign
Details
| ID | GetCampaignLowSimilarityIncidentsInfo |
|---|---|
| Language | python |
| From Version | 5.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Tags | dynamic-section |
README
Gets the campaign incidents with low similarity information as a markdown table.
This automation runs using the default Limited User role, unless you explicitly change the permissions.
For more information, see the section about permissions here: For Cortex XSOAR 6, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations for Cortex XSOAR 8 Cloud, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script for Cortex XSOAR 8 On-prem, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | dynamic-section |
| Cortex XSOAR Version | 5.5.0 |
Inputs
There are no inputs for this script.
Outputs
There are no outputs for this script.
from CommonServerPython import * from GetCampaignLowSimilarityIncidentsInfo import * REQUIRED_KEYS = ["id", "name", "emailfrom", "recipients", "severity", "status", "created"] STR_VAL_KEYS = ["name", "emailfrom", "recipients", "created"] NUM_OF_INCIDENTS = 5 MOCKED_INCIDENTS = [ {key.replace("_", ""): f"test_{key}_{i}" if key in STR_VAL_KEYS else i for key in REQUIRED_KEYS} for i in range(NUM_OF_INCIDENTS) ] UPDATED_MOCKED_INCIDENTS = [ {key.replace("_", ""): 3 if key in KEYS_FETCHED_BY_QUERY else i for key in REQUIRED_KEYS} for i in range(NUM_OF_INCIDENTS) ] SOME_ERROR = "Raised by mock of demisto.context" def raise_exception(): raise Exception(SOME_ERROR) def test_incidents_info_md_happy_path(mocker): """ Given: - Mocked incidents When: - Get the campaign incidents info Then: - Validate all required key and val are in the MD result """ # prepare mocker.patch("GetCampaignLowSimilarityIncidentsInfo.update_incident_with_required_keys") mocker.patch("GetCampaignLowSimilarityIncidentsInfo.get_campaign_incidents_from_context", return_value=MOCKED_INCIDENTS) mocker.patch.object(demisto, "results") mocker.patch.object(demisto, "incidents", return_value=MOCKED_INCIDENTS) mocker.patch.object(demisto, "executeCommand") mocker.patch.object(demisto, "context", return_value={"EmailCampaign": {"fieldsToDisplay": REQUIRED_KEYS}}) # run main() hr = demisto.results.call_args[0][0]["HumanReadable"] # validate required keys are header in the MD and the expected values are the table assert all(string_to_table_header(key) in hr for key in REQUIRED_KEYS) assert all(f"test_{key}_" in hr for key in STR_VAL_KEYS) assert all(status in hr for status in STATUS_DICT.values()) assert all(f"[{i}](#/Details/{i})" in hr for i in range(NUM_OF_INCIDENTS)) # linkable incident id # validate the call to update empty fields args = demisto.executeCommand.call_args[0][1] assert args["customFields"] == DEFAULT_CUSTOM_FIELDS def test_incidents_info_md_for_empty_context(mocker): """ Given: - There is no campaign incidents in context When: - Get the campaign incidents info Then: - Validate return message """ # prepare mocker.patch.object(demisto, "results") mocker.patch("GetCampaignLowSimilarityIncidentsInfo.get_campaign_incidents_from_context", return_value=[]) # run main() # validate assert demisto.results.call_args[0][0]["HumanReadable"] == NO_CAMPAIGN_INCIDENTS_MSG def test_incidents_info_md_with_invalid_keys(mocker): """ Given: - Incidents in campaign context contains some invalid keys (e.g. status), When: - Get value from incident (GetCampaignIncidentsInfo.get_incident_val) Then: - Validate invalid key not in the human readable """ # prepare incident_with_invalid_status = MOCKED_INCIDENTS[4] incident_without_status = MOCKED_INCIDENTS[0].copy() incident_without_status.pop("status") incidents = [incident_with_invalid_status, incident_without_status] mocker.patch.object(demisto, "results") mocker.patch("GetCampaignLowSimilarityIncidentsInfo.get_campaign_incidents_from_context", return_value=incidents) mocker.patch("GetCampaignLowSimilarityIncidentsInfo.update_incident_with_required_keys", return_value=incidents) # run main() hr = demisto.results.call_args[0][0]["HumanReadable"] # validate assert "Status" not in hr assert all(status not in hr for status in STATUS_DICT.values()) def test_some_error(mocker): """ Given: - Dynamic section try to populate the MD from script When: - Get incident info Then: - Raise exception and validate the return_error is called """ mocker.patch.object(demisto, "results") mocker.patch.object(demisto, "context", side_effect=raise_exception) mocker.patch("GetCampaignLowSimilarityIncidentsInfo.update_incident_with_required_keys") # run try: main() assert False, "SystemExit should occurred" # noqa: B011, PT015 except SystemExit: assert demisto.results.call_args[0][0]["Contents"] == SOME_ERROR def test_updated_status_and_severity(mocker): """ Given - Status or severity of incidents in campaign was changed When - Get the incidents info Then - Validate the updated values is returned """ # prepare mocker.patch.object(demisto, "results") mocker.patch("GetCampaignLowSimilarityIncidentsInfo.get_campaign_incidents_from_context", return_value=MOCKED_INCIDENTS) mocker.patch.object( demisto, "executeCommand", return_value=[{"Contents": json.dumps(UPDATED_MOCKED_INCIDENTS), "Type": "str"}] ) # run main() # validate hr = demisto.results.call_args[0][0]["HumanReadable"] hr.count("| Archive |") == NUM_OF_INCIDENTS # noqa: B015 # all incidents should have the 'Archive' status hr.count("| 3 |") == NUM_OF_INCIDENTS # noqa: B015 # all incidents should have severity 3