FindDuplicateEmailIncidents

Can be used to find duplicate emails for incidents of type phishing, including malicious, spam, and legitimate emails.

python · Phishing

Details

IDFindDuplicateEmailIncidents
Languagepython
From Version5.0.0
Docker Imagedemisto/sklearn:1.0.0.12545527
Tagsml phishing

README

Can be used to find duplicate emails for incidents of type phishing, including malicious, spam, and legitimate emails.

Script Data


Name Description
Script Type python3
Tags ml, phishing
Cortex XSOAR Version 5.0.0

Inputs


Argument Name Description
incidentTypeFieldName The name of the incident field where its type is stored. Default is “type”. Change this argument only in case you use a custom field for specifying incident type.
incidentTypes A comma-separated list of incident types by which to filter. The default is the current incident type. Specify “None” to ignore incident type from deduplication logic.
existingIncidentsLookback The start date by which to search for duplicated existing incidents. Date format is the same as in the incidents query page. For example, “3 days ago”, “2019-01-01T00:00:00 +0200”).
query Additional text by which to query incidents.
limit The maximum number of incidents to fetch.
emailSubject Subject of the email.
emailBody Body of the email.
emailBodyHTML HTML body of the email.
emailFrom Incident fields contains the email from value.
fromPolicy Whether to take into account the email from field for deduplication. “TextOnly” - incidents will be considered as duplicated based on test similarity only, ignoring the sender’s address. “Exact” - incidents will be considered as duplicated if their text is similar and their sender is the same. “Domain” - incidents will be considered as duplicated if their text is similar and their senders’ address has the same domain. Default is “Domain”.
statusScope Whether to compare the new incident to past closed or non closed incidents only.
closeAsDuplicate Whether to close the current incident if a duplicate incident is found. Only supported in Cortex XSOAR.
threshold Threshold to consider incident as duplication, number between 0-1
maxIncidentsToReturn Maximum number of duplicate incidents IDs to return.
populateFields A comma-separated list of incident fields to populate.
exsitingIncidentsLookback Deprecated. Use the *existingIncidentsLookback* argument instead.

Outputs


Path Description Type
duplicateIncident The oldest duplicate incident found with the highest similarity to the current incident. unknown
duplicateIncident.id Duplicate incident ID. string
duplicateIncident.rawId Duplicate incident ID. Unknown
duplicateIncident.name Duplicate incident name. Unknown
duplicateIncident.similarity Number in range 0-1 which describe the similarity between the existing incident and the new incident. Unknown
isDuplicateIncidentFound Whether a duplicate incident was found (“true” or “false”). boolean
allDuplicateIncidents All duplicate incidents found where their similarity with the new incident exceeds the threshold. Unknown
allDuplicateIncidents.id A list of all duplicate incidents IDs found. Unknown
allDuplicateIncidents.rawId A list of all duplicate incidents IDs found. Unknown
allDuplicateIncidents.name A list of all duplicate incidents names found. Unknown
allDuplicateIncidents.similarity A list of the similarity between duplicate incidents and new the incident of all duplicate incidents names found. Unknown
import json
from datetime import datetime

from CommonServerPython import *
from FindDuplicateEmailIncidents import *

EXISTING_INCIDENTS = []

RESULTS = None
EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None

IDS_COUNTER = 57878

text = (
    "Imagine there's no countries It isn't hard to do Nothing to kill or die for And no religion too "
    "Imagine all the people Living life in peace"
)
text2 = "Love of my life, you've hurt me You've broken my heart and now you leave me Love of my life, can't you see?\
      Bring it back, bring it back Don't take it away from me, because you don't know What it means to me"


def create_incident(subject=None, body=None, html=None, emailfrom=None, created=None, id_=None):
    global IDS_COUNTER
    dt_format = "%Y-%m-%d %H:%M:%S.%f %z"
    incident = {
        "CustomFields": {},
        "id": id_ if id_ is not None else str(IDS_COUNTER),
        "name": " ".join(str(x) for x in [subject, body, html, emailfrom]),
        "created": created.strftime(dt_format) if created is not None else datetime.now().strftime(dt_format),
        "type": "Phishing",
        "status": "1",
    }
    IDS_COUNTER += 1
    if subject is not None:
        incident["CustomFields"]["emailsubject"] = subject
    if body is not None:
        incident["CustomFields"]["emailbody"] = body
    if html is not None:
        incident["CustomFields"]["emailbodyhtml"] = html
    if emailfrom is not None:
        incident["CustomFields"]["emailfrom"] = emailfrom
    return incident


def set_existing_incidents_list(incidents_list):
    global EXISTING_INCIDENTS
    EXISTING_INCIDENTS = incidents_list


def executeCommand(command, args=None):
    global EXISTING_INCIDENTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    if command == "GetIncidentsByQuery":
        incidents_str = json.dumps(EXISTING_INCIDENTS)
        return [{"Contents": incidents_str, "Type": "not error"}]
    if command == "CloseInvestigationAsDuplicate":
        EXISTING_INCIDENT_ID = args["duplicateId"]
        return None
    return None


def results(arg):
    global RESULTS
    RESULTS = arg


def duplicated_incidents_found(existing_incident):
    return existing_incident["id"] == EXISTING_INCIDENT_ID


def test_same_incidents_text_only(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_different_text_only(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    text = (
        "Imagine there's no countries It isn't hard to do Nothing to kill or die for And no religion too "
        "Imagine all the people Living life in peace"
    )

    existing_incident = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert not duplicated_incidents_found(existing_incident)


def test_same_incidents_exact_sender_match_same_senders(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None

    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Exact"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_same_incidents_exact_sender_match_different_senders(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    text = (
        "Imagine there's no countries It isn't hard to do Nothing to kill or die for And no religion too "
        "Imagine all the people Living life in peace"
    )
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Exact"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user2@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert not duplicated_incidents_found(existing_incident)


def test_same_incidents_exact_sender_match_same_senders_different_texts(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None

    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Exact"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert not duplicated_incidents_found(existing_incident)


def test_same_incidents_domain_sender_match_same_senders(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Domain"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_same_incidents_domain_sender_match_same_domain(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Domain"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text, emailfrom="mt.kb.user2@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_same_incidents_domain_sender_match_same_domain_different_texts(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Domain"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text2, emailfrom="mt.kb.user2@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert not duplicated_incidents_found(existing_incident)


def test_slightly_different_texts(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body=text[:-5], emailfrom="mt.kb.user@gmail.co")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_html_text(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID, text, text2
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    html = f"<!DOCTYPE html>\
            <html>\
            <body>\
            <h1>{text}</h1>\
            <p>{text2}</p>\
            </body>\
            </html>\
            "
    clean_text = f"{text}\n{text2}"
    existing_incident = create_incident(body=clean_text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "Domain"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(html=html, emailfrom="mt.kb.user2@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_eliminate_urls_extensions():
    url = (
        "https://urldefense.proofpoint.com/v2/url?u=http-3A__hellothere.com_&d=DwIGaQ&c=XRWvQHnpdBDRh-yzrHjqLpXuH"
        "NC_9nanQc6pPG_SpT0&r=sUpl2dZrOIls7oQLXwn74C7qVYSZVCdsK9UIY1nPz30&m=qD-Bndy5WGvuZizr-Jz7YQ5-8xXgRcK3w8NnNzX"
        "lOsk&s=_NEaEUMVW0JU5b--ODhZKY9csky777X1jtFywaQyN2o&e="
    )
    url_shortened = eliminate_urls_extensions(url)
    assert url_shortened == "http://hellothere.com/"
    template = "hello world {} goodbye"
    assert template.format(url_shortened) == eliminate_urls_extensions(template.format(url))


def test_no_text_fields(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert "No text fields" in RESULTS["HumanReadable"]


def test_short_text(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body=text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body="short text")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert "too short" in RESULTS["HumanReadable"]


def test_generate_incident_type_query_component():
    type_fields_arg = "type1"
    type_values_arg = "hello world, hello world 2,hello world 3"
    res = generate_incident_type_query_component(type_fields_arg, type_values_arg)
    assert res == 'type1:("hello world" "hello world 2" "hello world 3")'


def test_linked_to_oldest_incident(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    dt1 = datetime.now()
    dt2 = datetime.now()
    existing_incident_1 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="1", created=dt1)
    existing_incident_2 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="2", created=dt2)

    set_existing_incidents_list([existing_incident_2, existing_incident_1])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body=text)
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert EXISTING_INCIDENT_ID == "1"


def test_linked_to_most_similar_incident(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    dt1 = datetime.now()
    dt2 = datetime.now()
    existing_incident_1 = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com", id_="1", created=dt1)
    existing_incident_2 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="2", created=dt2)

    set_existing_incidents_list([existing_incident_2, existing_incident_1])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body=text)
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert EXISTING_INCIDENT_ID == "2"


def test_linked_to_most_similar__and_oldest_incident(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident_1 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="1")
    existing_incident_2 = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com", id_="2")
    existing_incident_3 = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com", id_="3")
    existing_incident_4 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="4")
    set_existing_incidents_list([existing_incident_3, existing_incident_4, existing_incident_2, existing_incident_1])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body=text)
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert EXISTING_INCIDENT_ID == "1"


def test_tie_break_with_id(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    dt1 = datetime.now()
    dt2 = datetime.now()
    existing_incident_1 = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com", id_="1", created=dt1)
    existing_incident_2 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="2", created=dt2)
    existing_incident_3 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="3", created=dt2)
    set_existing_incidents_list([existing_incident_1, existing_incident_3, existing_incident_2])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body=text)
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert EXISTING_INCIDENT_ID == "2"


def test_tie_break_with_non_numeric_id(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    dt1 = datetime.now()
    dt2 = datetime.now()
    existing_incident_1 = create_incident(body=text2, emailfrom="mt.kb.user@gmail.com", id_="a", created=dt1)
    existing_incident_2 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="b", created=dt2)
    existing_incident_3 = create_incident(body=text, emailfrom="mt.kb.user@gmail.com", id_="c", created=dt2)
    set_existing_incidents_list([existing_incident_1, existing_incident_3, existing_incident_2])
    mocker.patch.object(demisto, "args", return_value={"fromPolicy": "TextOnly"})
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(emailfrom="mt.kb.user@gmail.co", body=text)
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert EXISTING_INCIDENT_ID == "b"


def test_similar_incidents_1_word_difference(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body="Hi Bob " + text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(
        demisto,
        "args",
        return_value={
            "fromPolicy": "TextOnly",
        },
    )
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body="Hi Jhon " + text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incident)


def test_similar_incidents_2_word_difference(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    existing_incident = create_incident(body="Hi Bob Burger" + text, emailfrom="mt.kb.user@gmail.com")
    set_existing_incidents_list([existing_incident])
    mocker.patch.object(
        demisto,
        "args",
        return_value={
            "fromPolicy": "TextOnly",
        },
    )
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body="Hi Jhon Pizza" + text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert not duplicated_incidents_found(existing_incident)


def test_multiple_incidents_word_difference(mocker):
    global RESULTS, EXISTING_INCIDENT_ID, DUP_INCIDENT_ID
    EXISTING_INCIDENT_ID = DUP_INCIDENT_ID = None
    email_body = "Hi Bob" + text
    existing_incidents_list = [create_incident(body=email_body, emailfrom="mt.kb.user@gmail.com") for _ in range(10)]
    set_existing_incidents_list(existing_incidents_list)
    mocker.patch.object(
        demisto,
        "args",
        return_value={
            "fromPolicy": "TextOnly",
        },
    )
    mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)
    new_incident = create_incident(body="Hi John" + text, emailfrom="mt.kb.user@gmail.com")
    mocker.patch.object(demisto, "incidents", return_value=[new_incident])
    mocker.patch.object(demisto, "results", side_effect=results)
    main()
    assert duplicated_incidents_found(existing_incidents_list[0])
    duplicate_ids_found = [res["id"] for res in RESULTS["EntryContext"]["allDuplicateIncidents"]]
    assert all(inc["id"] in duplicate_ids_found for inc in existing_incidents_list)


def test_empty_query(mocker):
    """

    Given:
        - Query argument as empty string

    When:
        - Parsing the query

    Then:
        - Assert that parsing the final query ignores the empty string
    """
    mocker.patch.object(
        demisto, "executeCommand", side_effect=lambda function_name, args: [{"Contents": json.dumps(args), "Type": -1}]
    )
    res = get_existing_incidents({"query": ""}, "Phishing")
    assert "()" not in res["query"]