Inventa

Use the Inventa integration to generate DSAR reports within Inventa instance and retrieve DSAR data for the XSOAR.

Data Enrichment & Threat Intelligence · Inventa

Details

IDInventa
ProviderInventaCapitalPLC
CategoryData Enrichment & Threat Intelligence
From Version5.5.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Use the Inventa integration to generate DSAR reports within Inventa instance and retrieve DSAR data for the XSOAR
This integration was integrated and tested with version 2.8.0 of Inventa

Configure 1Touch.io’s Inventa Connector in Cortex

Parameter Description Required
Your Inventa server URL   True
API Key The API Key to use for connection True
Trust any certificate (not secure)   False
Use system proxy settings   False

Commands

You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

inventa-get-datasubjects


Get Data Subject full details

Base Command

inventa-get-datasubjects

Input

| Argument Name | Description | Required |
| — | — | — |
| national_id | National ID of a PII. | Optional |
| passport_number | Passport Number of a PII. | Optional |
| driver_license | Driver’s License of a PII. | Optional |
| tax_id | Tax ID of a PII. | Optional |
| cc_number | Credit Card Number of a PII. | Optional |
| given_name | Given Name of a PII. | Optional |
| surname | Surname of a PII. | Optional |
| full_name | Full Name of a PII. | Optional |
| vehicle_number | Vehicle Number of a PII. | Optional |
| phone_number | Phone Number of a PII. | Optional |
| birthday | Birthday of a PII. | Optional |
| city | City of Resdence of a PII. | Optional |
| street_address | Street Address of a PII. | Optional |
Please note that all the arguments are optional, but they form a constraint which determines extraction of the right PII.
Following combinations are treated as constraints:

  • national_id
  • passport_number
  • driver_license
  • tax_id
  • cc_number
  • given_name + vehicle_number
  • given_name + phone_number
  • given_name + surname + birthday
  • given_name + surname + city + street_address
  • full_name + birthday
  • full_name + city + street_address

Context Output

Path Type Description
Inventa.DataSubjects.dataSubjects.id String ID of a Data Subject
Inventa.DataSubjects.dataSubjects.piis.id String ID of an Entity Type for the PII
Inventa.DataSubjects.dataSubjects.piis.piiEntityType String Entity Type name for the PII
Inventa.DataSubjects.dataSubjects.piis.piiEntityValue String Value of an Entity Type for the PII
Inventa.DataSubjects.dataSubjects.piis.piiEntityValueNew String New Value of an Entity Type for the PII
Inventa.DataSubjects.dataSubjects.piis.action String Action of an Entity Type for the PII
Inventa.DataSubjects.total String Total number of PII Entities found for the PII

Command Examples

!inventa-get-datasubjects national_id=12345678
!inventa-get-datasubjects passport_number=AB123456
!inventa-get-datasubjects driver_license=DL456789
!inventa-get-datasubjects tax_id=1234567890
!inventa-get-datasubjects cc_number=1234567890123456
!inventa-get-datasubjects given_name=john vehicle_number=AB456CD
!inventa-get-datasubjects given_name=john phone_number=1234567890
!inventa-get-datasubjects given_name=john surname=smith birthday=01/20/86
!inventa-get-datasubjects given_name=john surname=smith city=vancouver street_address="main square 1"
!inventa-get-datasubjects full_name="john smith" birthday=01/20/86
!inventa-get-datasubjects full_name="john smith" city=vancouver street_address="main square 1"

inventa-get-sources


Retrieves data sources’ details containing info about data subject

Base Command

inventa-get-sources

Input

Argument Name Description Required
datasubject_id ID of a datasubject within Inventa. Required

Context Output

Path Type Description
Inventa.Sources.sources.id String Id of a source containing info about data subject
Inventa.Sources.sources.applianceName String Data sources conteining info related to a PII
Inventa.Sources.sources.timestamp String Timestamp of a source containing info about data subject
Inventa.Sources.sources.keyType String KeyType of a source containing info about data subject
Inventa.Sources.sources.path String Path of a source containing info about data subject
Inventa.Sources.sources.url String URL of a source containing info about data subject
Inventa.Sources.sources.hostname String Hostname of a source containing info about data subject
Inventa.Sources.sources.dbName String DB name of a source containing info about data subject
Inventa.Sources.sources.vendor String Vendor of a source containing info about data subject
Inventa.Sources.sources.type String Type of a source containing info about data subject
Inventa.Sources.sources.context String Additional info on a source containing info about data subject
Inventa.Sources.sources.entityTypes String Types of sensitive data stored in a source containing info about data subject

Command Example

!inventa-get-sources datasubject_id=123asd123

inventa-get-sources-piis


Retrieves PII entities stored in data sources related to datasubject

Base Command

inventa-get-sources-piis

Input

Argument Name Description Required
datasubject_id ID of a datasubject within Inventa. Required

Context Output

Path Type Description
Inventa.Sources.piis String PII entity types in sources

Command Example

!inventa-get-sources-piis datasubject_id=123asd123

inventa-get-dsar-transactions


Retrieves data transactions’ details containing info about data subject

Base Command

inventa-get-dsar-transactions

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DSAR.Transactions.transactions String List of data transactions

Command Example

!inventa-get-dsar-transactions ticket_id=3

inventa-get-dsar-files


Retrieves details of files contatining info about data subject

Base Command

inventa-get-dsar-files

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DSAR.Files.files String List of files containing info about data subject

Command Example

!inventa-get-dsar-files ticket_id=3

inventa-get-dsar-databases


Retrieves list of databases and tables containing info about data subject

Base Command

inventa-get-dsar-databases

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DSAR.DataBases.databases String List of datatables containing info about data subject

Command Example

!inventa-get-dsar-databases ticket_id=3

inventa-get-datasubject-details


Get datasubject name and email

Base Command

inventa-get-datasubject-details

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DataSubject.name String Name of a data subject
Inventa.DataSubject.email String Email address of a data subject

Command Example

!inventa-get-datasubject-details ticket_id = 3

inventa-get-dsar-dataassets


Retrieves list of data assets containing info about data subject

Base Command

inventa-get-dsar-dataassets

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DSAR.DataAssets.dataAssets String List of data assets containing info about data subject

Command Example

inventa-get-dsar-dataassets ticket_id=3

inventa-get-dsar-piis


Get list of PII categories related to the data subject

Base Command

inventa-get-dsar-piis

Input

Argument Name Description Required
ticket_id ID of a DSAR ticket within Inventa. Required

Context Output

Path Type Description
Inventa.DSAR.piis String List of PII categories related to data subject

Command Example

!inventa-get-dsar-piis ticket_id=3

inventa-get-entities


Retrieves list of PII entities described in Inventa

Base Command

inventa-get-entities

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
Inventa.Entities.entity String List of PII entities described in Inventa

Command Example


### inventa-get-datasubject-id-from-ticket

***
Retrieves ID of a data subject from Inventa's DSAR ticket

#### Base Command

`inventa-get-datasubject-id-from-ticket`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| ticket_id | ID of a DSAR ticket within Inventa. | Required |

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Inventa.DataSubjects.datasubject_id | String | ID of a data subject within Inventa |

#### Command Example

```!inventa-get-datasubject-id-from-ticket ticket_id=3```

### inventa-get-datasubject-id

***
Retrieves ID of a data subject from passed constraints

#### Base Command

`inventa-get-datasubject-id`

#### Input

| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| national_id | National ID of a PII. | Optional |
| passport_number | Passport Number of a PII. | Optional |
| driver_license | Driver's License of a PII. | Optional |
| tax_id | Tax ID of a PII. | Optional |
| cc_number | Credit Card Number of a PII. | Optional |
| given_name | Given Name of a PII. | Optional |
| surname | Surname of a PII. | Optional |
| full_name | Full Name of a PII. | Optional |
| vehicle_number | Vehicle Number of a PII. | Optional |
| phone_number | Phone Number of a PII. | Optional |
| birthday | Birthday of a PII. | Optional |
| city | City of Resdence of a PII. | Optional |
| street_address | Street Address of a PII. | Optional |
Please note that all the arguments are optional, but they form a constraint which determines extraction of the right PII.
Following combinations are treated as constraints:

* national_id
* passport_number
* driver_license
* tax_id
* cc_number
* given_name + vehicle_number
* given_name + phone_number
* given_name + surname + birthday
* given_name + surname + city + street_address
* full_name + birthday
* full_name + city + street_address

#### Context Output

| **Path** | **Type** | **Description** |
| --- | --- | --- |
| Inventa.DataSubjects.datasubject_id | String | ID of a data subject within Inventa |

#### Command Example

!inventa-get-datasubjects national_id=12345678
!inventa-get-datasubjects passport_number=AB123456
!inventa-get-datasubjects driver_license=DL456789
!inventa-get-datasubjects tax_id=1234567890
!inventa-get-datasubjects cc_number=1234567890123456
!inventa-get-datasubjects given_name=john vehicle_number=AB456CD
!inventa-get-datasubjects given_name=john phone_number=1234567890
!inventa-get-datasubjects given_name=john surname=smith birthday=01/20/86
!inventa-get-datasubjects given_name=john surname=smith city=vancouver street_address=”main square 1”
!inventa-get-datasubjects full_name=”john smith” birthday=01/20/86
!inventa-get-datasubjects full_name=”john smith” city=vancouver street_address=”main square 1”
```

inventa-create-ticket


Creates Inventa ticket

Base Command

inventa-create-ticket

Input

Argument Name Description Required
reason Reason for DSAR report. Required
datasubject_id ID of a data subject within Inventa. Required

Context Output

Path Type Description
Inventa.DataSubjects.Ticket.ticket_id String ID of a DSAR ticket, created within Inventa

Command Example

!inventa-create-ticket reason="test reason" datasubject_id=123asd456789

inventa-validate-incident-inputs


Validates Incident inputs

Base Command

inventa-validate-incident-inputs

Input

| Argument Name | Description | Required |
| — | — | — |

Context Output

Path Type Description
Inventa.Incident.validated Boolean Whether inputs are valid

Command Example

!inventa-validate-incident-inputs

Configuration parameters

  • url — Your Inventa server URL (required)
  • apikey — API Key (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (14)

  • inventa-create-ticket

    Creates Inventa ticket.

  • inventa-get-datasubject-details

    Get datasubject name and email.

  • inventa-get-datasubject-id

    Retrieves ID of a data subject from passed constraints.

  • inventa-get-datasubject-id-from-ticket

    Retrieves ID of a data subject from Inventa's DSAR ticket.

  • inventa-get-datasubjects

    Get Data Subject full details.

  • inventa-get-dsar-dataassets

    Retrieves list of data assets containing info about data subject.

  • inventa-get-dsar-databases

    Retrieves list of databases and tables containing info about data subject.

  • inventa-get-dsar-files

    Retrieves details of files contatining info about data subject.

  • inventa-get-dsar-piis

    Get list of PII categories related to the data subject.

  • inventa-get-dsar-transactions

    Retrieves data transactions' details containing info about data subject.

  • inventa-get-entities

    Retrieves list of PII entities described in Inventa.

  • inventa-get-sources

    Get sources details.

  • inventa-get-sources-piis

    Get PII details from daatasubjest.

  • inventa-validate-incident-inputs

    Validates incident's inputs.

"""Base Integration for Cortex XSOAR - Unit Tests file

Pytest Unit Tests: all funcion names must start with "test_"

More details: https://xsoar.pan.dev/docs/integrations/unit-testing

MAKE SURE YOU REVIEW/REPLACE ALL THE COMMENTS MARKED AS "TODO"

You must add at least a Unit Test function for every XSOAR command
you are implementing with your integration
"""

import json

import demistomock as demisto
from Inventa import Client, format_pii_entities, generate_datasubject_payload, main, validate_incident_inputs_command
from pytest import raises  # noqa: PT013

constraints_cmds = ["inventa-get-datasubjects", "inventa-get-datasubject-id"]

datasubjectid_cmds = ["inventa-get-sources", "inventa-get-sources-piis"]

ticket_cmds = [
    "inventa-get-datasubject-details",
    "inventa-get-dsar-piis",
    "inventa-get-dsar-transactions",
    "inventa-get-dsar-files",
    "inventa-get-dsar-databases",
    "inventa-get-dsar-dataassets",
    "inventa-get-datasubject-id-from-ticket",
]

reason_cmds = ["inventa-create-ticket"]

noarg_cmds = ["inventa-get-entities"]

mock_arguments_datasubjectid = {"datasubject_id": "TEST_DATASUBJECT_ID"}

mock_arguments_constraints = {
    "national_id": "TEST_NATIONAL_ID",
    "passport_number": "TEST_PASSPORT_NUMBER",
    "driver_license": "TEST_DRIVER_LICENSE",
    "tax_id": "TEST_TAX_ID",
    "cc_number": "TEST_CC_NUMBER",
    "given_name": "TEST_GIVEN_NAME",
    "surname": "TEST_SURNAME",
    "full_name": "TEST_FULL_NAME",
    "vehicle_number": "TEST_VEHICLE_NUMBER",
    "phone_number": "TEST_PHONE_NUMBER",
    "birthday": "TEST_BIRTHDAY",
    "city": "TEST_CITY",
    "street_address": "TEST_STREET_ADDRESS",
}
mock_arguments_constraints_fail = {"given_name": "TEST_GIVEN_NAME", "surname": "TEST_SURNAME"}
mock_arguments_ticket = {"ticket_id": "TEST_TICKET_ID"}

mock_arguments_reason_dsid = {"reason": "TEST_REASON", "datasubject_id": "TEST_DATASUBJECT_ID"}

mock_demisto_params = {"url": "--TEST URL--", "apikey": "---TEST_API_KEY---", "insecure": "True"}


def mock_params():
    return mock_demisto_params


def mock_args(command_name):
    if command_name in constraints_cmds:
        return mock_arguments_constraints
    if command_name in datasubjectid_cmds:
        return mock_arguments_datasubjectid
    if command_name in reason_cmds:
        return mock_arguments_reason_dsid
    if command_name in ticket_cmds:
        return mock_arguments_ticket
    if command_name in noarg_cmds:
        return {}
    raise ValueError(f"Unimplemented command called: {command_name}")


def util_load_json(path):
    with open(path, encoding="utf-8") as f:
        return json.loads(f.read())


mock_data = util_load_json("test_data/test_commands.json")
mock_response = util_load_json("test_data/test_client.json")

client_get_entities_mock_data = mock_response.get("get_entities", "")
client_get_datasubject_mock_data = mock_response.get("get_datasubject", "")
client_prepare_ticket_mock_data = mock_response.get("prepare_ticket", "")
client_create_ticket_mock_data = mock_response.get("create_ticket", "")
client_get_ticket_mock_data = mock_response.get("get_ticket", "")
client_get_dsar_mock_data = mock_response.get("get_dsar", "")

get_entities_cmd_mock_data = mock_data.get("inventa-get-entities", "")
get_datasubjects_cmd_mock_data = mock_data.get("inventa-get-datasubjects", "")
get_datasubject_id_cmd_mock_data = mock_data.get("inventa-get-datasubject-id", "")
create_ticket_cmd_mock_data = mock_data.get("inventa-create-ticket", "")
get_datasubjectid_from_ticket_cmd_mock_data = mock_data.get("inventa-get-datasubject-id-from-ticket", "")
get_datasubject_details_cmd_mock_data = mock_data.get("inventa-get-datasubject-details", "")
get_dsar_piis_cmd_mock_data = mock_data.get("inventa-get-dsar-piis", "")
get_dsar_files_cmd_mock_data = mock_data.get("inventa-get-dsar-files", "")
get_dsar_databases_cmd_mock_data = mock_data.get("inventa-get-dsar-databases", "")
get_dsar_transactions_cmd_mock_data = mock_data.get("inventa-get-dsar-transactions", "")
get_dsar_dataassets_cmd_mock_data = mock_data.get("inventa-get-dsar-dataassets", "")


def executeCommand(command, args=None):
    return mock_data.get(command, "")


def executeClient(method, args=None):
    return mock_response.get(method, "")


def mocker_automate(mocker, command_name, method_names):
    mocker.patch.object(demisto, "params", return_value=mock_params())
    mocker.patch.object(demisto, "args", return_value=mock_args(command_name))
    mocker.patch.object(demisto, "command", return_value=command_name)
    mocker.patch.object(demisto, "results")
    for method_name in method_names:
        mocker.patch.object(Client, method_name, return_value=executeClient(method_name))


def test_get_entities_cmd(mocker):
    command_name = "inventa-get-entities"
    method_name = "get_entities"

    mocker_automate(mocker, command_name, [method_name])

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_datasubjects_cmd(mocker):
    command_name = "inventa-get-datasubjects"
    method_name = "get_datasubject"

    mocker_automate(mocker, command_name, [method_name])

    NATIONAL_ID = demisto.args().get("national_id", "")
    PASSPORT_NUMBER = demisto.args().get("passport_number", "")
    DRIVER_LICENSE = demisto.args().get("driver_license", "")
    TAX_ID = demisto.args().get("tax_id", "")
    CC_NUMBER = demisto.args().get("cc_number", "")
    GIVEN_NAME = demisto.args().get("given_name", "")
    SURNAME = demisto.args().get("surname", "")
    FULL_NAME = demisto.args().get("full_name", "")
    VEHICLE_NUMBER = demisto.args().get("vehicle_number", "")
    PHONE_NUMBER = demisto.args().get("phone_number", "")
    BIRTHDAY = demisto.args().get("birthday", "")
    CITY = demisto.args().get("city", "")
    STREET_ADDRESS = demisto.args().get("street_address", "")

    # test presence of constraints
    constraints = [
        NATIONAL_ID,
        PASSPORT_NUMBER,
        DRIVER_LICENSE,
        TAX_ID,
        CC_NUMBER,
        (GIVEN_NAME and VEHICLE_NUMBER),
        (GIVEN_NAME and PHONE_NUMBER),
        (GIVEN_NAME and SURNAME and BIRTHDAY),
        (GIVEN_NAME and SURNAME and CITY and STREET_ADDRESS),
        (FULL_NAME and BIRTHDAY),
        (FULL_NAME and CITY and STREET_ADDRESS),
    ]

    constraint_passed = False
    for constraint in constraints:
        if constraint:
            constraint_passed = True
            break

    assert constraint_passed

    # test passed values
    assert NATIONAL_ID == "TEST_NATIONAL_ID"
    assert PASSPORT_NUMBER == "TEST_PASSPORT_NUMBER"
    assert DRIVER_LICENSE == "TEST_DRIVER_LICENSE"
    assert TAX_ID == "TEST_TAX_ID"
    assert CC_NUMBER == "TEST_CC_NUMBER"
    assert GIVEN_NAME == "TEST_GIVEN_NAME"
    assert SURNAME == "TEST_SURNAME"
    assert FULL_NAME == "TEST_FULL_NAME"
    assert VEHICLE_NUMBER == "TEST_VEHICLE_NUMBER"
    assert PHONE_NUMBER == "TEST_PHONE_NUMBER"
    assert BIRTHDAY == "TEST_BIRTHDAY"
    assert CITY == "TEST_CITY"
    assert STREET_ADDRESS == "TEST_STREET_ADDRESS"

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]

    A = results[0]["Contents"]
    B = mock_data.get(command_name, "")[0]

    assert A["id"] == B["id"]
    assert "|".join(A["personalInfo"]) == "|".join(B["personalInfo"])
    assert A["sourceIds"] == B["sourceIds"]
    assert A["rdaSourceIds"] == B["rdaSourceIds"]
    assert A["timestamp"] == B["timestamp"]


def test_get_datasubject_id_cmd(mocker):
    command_name = "inventa-get-datasubject-id"
    method_name = "get_datasubject"

    mocker_automate(mocker, command_name, [method_name])

    NATIONAL_ID = demisto.args().get("national_id", "")
    PASSPORT_NUMBER = demisto.args().get("passport_number", "")
    DRIVER_LICENSE = demisto.args().get("driver_license", "")
    TAX_ID = demisto.args().get("tax_id", "")
    CC_NUMBER = demisto.args().get("cc_number", "")
    GIVEN_NAME = demisto.args().get("given_name", "")
    SURNAME = demisto.args().get("surname", "")
    FULL_NAME = demisto.args().get("full_name", "")
    VEHICLE_NUMBER = demisto.args().get("vehicle_number", "")
    PHONE_NUMBER = demisto.args().get("phone_number", "")
    BIRTHDAY = demisto.args().get("birthday", "")
    CITY = demisto.args().get("city", "")
    STREET_ADDRESS = demisto.args().get("street_address", "")

    # test presence of constraints
    constraints = [
        NATIONAL_ID,
        PASSPORT_NUMBER,
        DRIVER_LICENSE,
        TAX_ID,
        CC_NUMBER,
        (GIVEN_NAME and VEHICLE_NUMBER),
        (GIVEN_NAME and PHONE_NUMBER),
        (GIVEN_NAME and SURNAME and BIRTHDAY),
        (GIVEN_NAME and SURNAME and CITY and STREET_ADDRESS),
        (FULL_NAME and BIRTHDAY),
        (FULL_NAME and CITY and STREET_ADDRESS),
    ]

    constraint_passed = False
    for constraint in constraints:
        if constraint:
            constraint_passed = True
            break

    assert constraint_passed

    # test passed values
    assert NATIONAL_ID == "TEST_NATIONAL_ID"
    assert PASSPORT_NUMBER == "TEST_PASSPORT_NUMBER"
    assert DRIVER_LICENSE == "TEST_DRIVER_LICENSE"
    assert TAX_ID == "TEST_TAX_ID"
    assert CC_NUMBER == "TEST_CC_NUMBER"
    assert GIVEN_NAME == "TEST_GIVEN_NAME"
    assert SURNAME == "TEST_SURNAME"
    assert FULL_NAME == "TEST_FULL_NAME"
    assert VEHICLE_NUMBER == "TEST_VEHICLE_NUMBER"
    assert PHONE_NUMBER == "TEST_PHONE_NUMBER"
    assert BIRTHDAY == "TEST_BIRTHDAY"
    assert CITY == "TEST_CITY"
    assert STREET_ADDRESS == "TEST_STREET_ADDRESS"

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_sources_cmd(mocker):
    command_name = "inventa-get-sources"
    method_name = "get_sources"

    mocker_automate(mocker, command_name, [method_name])

    DATASUBJECT_ID = demisto.args().get("datasubject_id", "")

    assert DATASUBJECT_ID == "TEST_DATASUBJECT_ID"

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    A = results[0]["Contents"][0]
    B = mock_data.get(command_name, "")[0]
    assert A["id"] == B["id"]
    assert A["applianceName"] == B["applianceName"]
    assert A["timestamp"] == B["timestamp"]
    assert A["keyType"] == B["keyType"]
    assert A["path"] == B["path"]
    assert A["url"] == B["url"]
    assert A["hostName"] == B["hostName"]
    assert A["dbName"] == B["dbName"]
    assert A["vendor"] == B["vendor"]
    assert A["type"] == B["type"]
    assert A["content"] == json.dumps(B["content"])
    assert A["entityTypes"] == ", ".join(B["entityTypes"])


def test_get_sources_piis_cmd(mocker):
    command_name = "inventa-get-sources-piis"
    method_name = "get_sources"

    mocker_automate(mocker, command_name, [method_name])

    DATASUBJECT_ID = demisto.args().get("datasubject_id", "")

    assert DATASUBJECT_ID == "TEST_DATASUBJECT_ID"

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    A = results[0]["Contents"]
    B = mock_data.get(command_name, "")
    assert A == B


def test_create_ticket_cmd(mocker):
    command_name = "inventa-create-ticket"
    method_name_1 = "prepare_ticket"
    method_name_2 = "create_ticket"

    mocker_automate(mocker, command_name, [method_name_1, method_name_2])

    assert demisto.args()["datasubject_id"] == "TEST_DATASUBJECT_ID"
    assert demisto.args()["reason"] == "TEST_REASON"

    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_datasubject_details_cmd(mocker):
    command_name = "inventa-get-datasubject-details"
    method_name = "get_ticket"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_datasubjectid_from_ticket_cmd(mocker):
    command_name = "inventa-get-datasubject-id-from-ticket"
    method_name = "get_ticket"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_dsar_piis_cmd(mocker):
    command_name = "inventa-get-dsar-piis"
    method_name = "get_dsar"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    piis_1 = []
    piis_2 = []
    piis_1.extend(results[0]["Contents"]["piis"])
    piis_2.extend(mock_data.get(command_name, "")["piis"])
    piis_1.sort()
    piis_2.sort()
    assert piis_1 == piis_2


def test_get_dsar_files_cmd(mocker):
    command_name = "inventa-get-dsar-files"
    method_name = "get_dsar"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]

    files_1 = results[0]["Contents"]["files"]
    files_2 = mock_data.get(command_name, "")["files"]

    files_1.sort(key=lambda x: x["id"])
    files_2.sort(key=lambda x: x["id"])

    assert len(files_1) == len(files_2)

    for index in range(len(files_1)):
        file_1 = files_1[index]
        file_2 = files_2[index]
        entity_types_1 = file_1["entityTypes"]
        entity_types_2 = file_2["entityTypes"]
        entity_types_1 = set(entity_types_1.split(", "))
        entity_types_2 = set(entity_types_2.split(", "))

        assert entity_types_1 == entity_types_2
        assert file_1["id"] == file_2["id"]
        assert file_1["name"] == file_2["name"]
        assert file_1["path"] == file_2["path"]
        assert file_1["size"] == file_2["size"]
        assert file_1["timestamp"] == file_2["timestamp"]
        assert file_1["url"] == file_2["url"]


def test_get_dsar_transactions_cmd(mocker):
    command_name = "inventa-get-dsar-transactions"
    method_name = "get_dsar"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]
    assert results[0]["Contents"] == mock_data.get(command_name, "")


def test_get_dsar_databases_cmd(mocker):
    command_name = "inventa-get-dsar-databases"
    method_name = "get_dsar"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]

    databases_1 = results[0]["Contents"]["databases"]
    databases_2 = mock_data.get(command_name, "")["databases"]

    databases_1.sort(key=lambda x: f"{x['database']}.{x['name']}")
    databases_2.sort(key=lambda x: f"{x['database']}.{x['name']}")

    assert len(databases_1) == len(databases_2)

    for index in range(len(databases_1)):
        db_1 = databases_1[index]
        db_2 = databases_2[index]
        assert db_1["id"] == db_2["id"]
        assert db_1["name"] == db_2["name"]
        assert db_1["database"] == db_2["database"]
        entity_types_1 = db_1["entityTypes"]
        entity_types_2 = db_2["entityTypes"]
        entity_types_1 = set(entity_types_1.split(", "))
        entity_types_2 = set(entity_types_2.split(", "))
        assert entity_types_1 == entity_types_2


def test_get_dsar_dataassets_cmd(mocker):
    command_name = "inventa-get-dsar-dataassets"
    method_name = "get_dsar"

    mocker_automate(mocker, command_name, [method_name])

    assert demisto.args()["ticket_id"] == "TEST_TICKET_ID"
    main()
    assert demisto.results.call_count == 1
    results = demisto.results.call_args[0]

    dataassets_1 = results[0]["Contents"]["dataAssets"]
    dataassets_2 = mock_data.get(command_name, "")["dataAssets"]

    dataassets_1.sort(key=lambda x: x["id"])
    dataassets_2.sort(key=lambda x: x["id"])

    assert len(dataassets_1) == len(dataassets_2)

    for index in range(len(dataassets_1)):
        dataasset_1 = dataassets_1[index]
        dataasset_2 = dataassets_2[index]
        piis_1 = dataasset_1["piis"]
        piis_2 = dataasset_2["piis"]
        piis_1 = set(piis_1.split(", "))
        piis_2 = set(piis_2.split(", "))
        reasons_1 = dataasset_1["reasonsOfProcessing"]
        reasons_2 = dataasset_2["reasonsOfProcessing"]
        reasons_1 = set(reasons_1.split(", "))
        reasons_2 = set(reasons_2.split(", "))

        assert piis_1 == piis_2
        assert dataasset_1["id"] == dataasset_2["id"]
        assert dataasset_1["name"] == dataasset_2["name"]
        assert dataasset_1["description"] == dataasset_2["description"]
        assert reasons_1 == reasons_2


def test_validate_incident_inputs_cmd(mocker):
    command_name = "inventa-get-dsar-dataassets"
    mocker_automate(mocker, command_name, [])

    NATIONAL_ID = demisto.args().get("national_id", "")
    PASSPORT_NUMBER = demisto.args().get("passport_number", "")
    DRIVER_LICENSE = demisto.args().get("driver_license", "")
    TAX_ID = demisto.args().get("tax_id", "")
    CC_NUMBER = demisto.args().get("cc_number", "")
    GIVEN_NAME = demisto.args().get("given_name", "")
    SURNAME = demisto.args().get("surname", "")
    FULL_NAME = demisto.args().get("full_name", "")
    VEHICLE_NUMBER = demisto.args().get("vehicle_number", "")
    PHONE_NUMBER = demisto.args().get("phone_number", "")
    BIRTHDAY = demisto.args().get("birthday", "")
    CITY = demisto.args().get("city", "")
    STREET_ADDRESS = demisto.args().get("street_address", "")
    TICKET_ID = demisto.args().get("ticket_id", "")
    DATASUBJECT_ID = demisto.args().get("datasubject_id", "")

    # test presence of constraints
    constraints = [
        TICKET_ID,
        DATASUBJECT_ID,
        NATIONAL_ID,
        PASSPORT_NUMBER,
        DRIVER_LICENSE,
        TAX_ID,
        CC_NUMBER,
        (GIVEN_NAME and VEHICLE_NUMBER),
        (GIVEN_NAME and PHONE_NUMBER),
        (GIVEN_NAME and SURNAME and BIRTHDAY),
        (GIVEN_NAME and SURNAME and CITY and STREET_ADDRESS),
        (FULL_NAME and BIRTHDAY),
        (FULL_NAME and CITY and STREET_ADDRESS),
    ]

    constraint_passed = False
    for constraint in constraints:
        if constraint:
            constraint_passed = True
            break

    assert constraint_passed

    with raises(Exception, match="Validation failed: constraints missing. Check incident's inputs."):
        validate_incident_inputs_command(**mock_arguments_constraints_fail)


def test_generate_datasubject_payload():
    pii_entities = ["CC_CVV", "CC_NUMBER", "CC_TYPE"]
    test_kwargs = {
        "national_id": "TEST NATIONAL ID",
        "given_name": "TEST NAME",
        "cc_cvv": "TEST_CC_CVV",
        "cc_number": "TEST_CC_NUMBER",
        "cc_type": "TEST_CC_TYPE",
    }
    payload = generate_datasubject_payload(pii_entities, **test_kwargs)
    test_payload = [
        {"piiEntityType": "CC_CVV", "piiEntityValue": "TEST_CC_CVV"},
        {"piiEntityType": "CC_NUMBER", "piiEntityValue": "TEST_CC_NUMBER"},
        {"piiEntityType": "CC_TYPE", "piiEntityValue": "TEST_CC_TYPE"},
    ]
    assert test_payload == payload


def test_format_pii_entities():
    entities = {
        "Demographic": [{"entityName": "BIRTHDAY", "sensitive": False}],
        "Digital Identification": [
            {"entityName": "BROWSER_USER_AGENT", "sensitive": False},
            {"entityName": "GUID", "sensitive": False},
        ],
        "Financial information": [
            {"entityName": "ACCOUNT_NUMBER", "sensitive": False},
            {"entityName": "CC_CVV", "sensitive": True},
            {"entityName": "CC_EXPIRES", "sensitive": False},
            {"entityName": "CC_NUMBER", "sensitive": False},
            {"entityName": "CC_TYPE", "sensitive": False},
        ],
    }

    test_value = {
        "entities": ["BIRTHDAY", "BROWSER_USER_AGENT", "GUID", "ACCOUNT_NUMBER", "CC_CVV", "CC_EXPIRES", "CC_NUMBER", "CC_TYPE"]
    }

    assert format_pii_entities(entities) == test_value