AddKeyToList

Adds/Replaces a key in key/value store backed by an XSOAR list.

python · Common Scripts

Details

IDAddKeyToList
Languagepython
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10404775

README

Adds/Replaces a key in key/value store backed by an XSOAR list.

Script Data


Name Description
Script Type python3
Tags  
Cortex XSOAR Version 5.0.0

Inputs


Argument Name Description
listName List name.
keyName Key.
value Key Value.
append Append to key.
allowDups Allow duplicates in array keys.

Outputs


There are no outputs for this script.

Script Example

!AddKeyToList listName="NewList" keyName="SomeKey" value="TestValue"

Context Example

{}

Human Readable Output

Successfully updated list NewList.

import json
from typing import Any

import demistomock as demisto  # noqa # pylint: disable=unused-wildcard-import
from AddKeyToList import add_key_to_list_command

MOCK_LIST_NAME = "TestList"
MOCK_KEY_NAME = "TestKey"
MOCK_VALUE = "TestValue"


def test_add_new_key_in_empty_list(mocker):
    """
    Given:
        - a starting empty list
        - a key and value pair
    When
        - adding a key/value to an empty list
    Then
        - key/value successfully added (list contains only the key/value)
        - success message is returned
    """
    MOCKED_START_LIST: dict = {}
    MOCKED_END_LIST: dict = {MOCK_KEY_NAME: MOCK_VALUE}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "false", "allowDups": "false"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST


def test_add_new_key_in_nonempty_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair
        - a key and value pair (different from the existing one)
    When
        - adding a key/value to a nonempty list
    Then
        - key/value successfully added (list contains both old and new key/value pairs)
        - success message is returned
    """
    MOCKED_START_LIST: dict = {"ExistingKey": "ExistingValue"}
    MOCKED_END_LIST: dict = {"ExistingKey": "ExistingValue", MOCK_KEY_NAME: MOCK_VALUE}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "false", "allowDups": "false"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST


def test_replace_key_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair
        - a key and value pair (same key but differnt value from the existing one)
        - append is false
        - allow duplicate values is false
    When
        - replacing value for an existing key in a nonempty list
    Then
        - value for key successfully replaced (list contains only new key/value pair)
        - success message is returned
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: "OldValue"}
    MOCKED_END_LIST: dict = {MOCK_KEY_NAME: MOCK_VALUE}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "false", "allowDups": "false"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST


def test_no_change_same_value_same_key_no_dup_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair
        - a key and value pair (same as the existing one)
        - append is true
        - allow duplicate values is false
    When
        - adding a key/value to a nonempty list that already contains same key/value
    Then
        - list is not changed
        - return message says that list wasn't changed as value already exists for key
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: MOCK_VALUE}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "true", "allowDups": "false"}
    )

    assert result.readable_output == f"Value already present in key {MOCK_KEY_NAME} of list {MOCK_LIST_NAME}: not appending."
    assert len(mocked_ec.call_args_list) == 1


def test_append_value_to_existing_key_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair
        - a key and value pair (same key as the existing one, different value)
        - append is true
        - allow duplicate values is false
    When
        - adding a key/value to a nonempty list that already contains same key with a different value
    Then
        - value for the key is transformed into a list containing both old and new value
        - success message is returned
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: "OldValue"}
    MOCKED_END_LIST: dict = {MOCK_KEY_NAME: ["OldValue", MOCK_VALUE]}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "true", "allowDups": "false"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST


def test_append_value_to_existing_list_key_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair (value is a list with 2 items)
        - a key and value pair (same key as the existing one, different value)
        - append is true
        - allow duplicate values is false
    When
        - adding a key/value to a nonempty list that already contains same key with a list of values (different from input one)
    Then
        - new value for the key is appended to the existing list for that key
        - success message is returned
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: ["OldValue1", "OldValue2"]}
    MOCKED_END_LIST: dict = {MOCK_KEY_NAME: ["OldValue1", "OldValue2", MOCK_VALUE]}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "true", "allowDups": "false"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST


def test_no_append_existing_value_same_list_key_no_dup_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair (value is a list with 2 items)
        - a key and value pair (same key as the existing one, value is already in the existing list)
        - append is true
        - allow duplicate values is false
    When
        - adding a key/value to a nonempty list that already contains same key with a list of values (including the input one)
    Then
        - list is not changed
        - return message says that list wasn't changed as value already exists for key
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: ["OldValue", MOCK_VALUE]}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "true", "allowDups": "false"}
    )

    assert result.readable_output == f"Value already present in key {MOCK_KEY_NAME} of list {MOCK_LIST_NAME}: not appending."
    assert len(mocked_ec.call_args_list) == 1


def test_append_duplicate_value_to_existing_key_in_existing_list(mocker):
    """
    Given:
        - a starting list with one existing key/value pair
        - a key and value pair (same key as the existing one)
        - append is true
        - allow duplicate values is true
    When
        - adding a key/value to a nonempty list that already contains same key with the same value and dups allowed
    Then
        - value for the key is changed in a list that contains the same value twice
        - return success message
    """
    MOCKED_START_LIST: dict = {MOCK_KEY_NAME: MOCK_VALUE}
    MOCKED_END_LIST: dict = {MOCK_KEY_NAME: [MOCK_VALUE, MOCK_VALUE]}

    def executeCommand(name: str, args: dict[str, Any]) -> list[dict[str, Any]]:
        if name == "getList":
            return [{"Contents": json.dumps(MOCKED_START_LIST)}]
        elif name == "setList":
            return [{"Contents": f"Done: list {name} was updated"}]

        raise ValueError(f"Error: Unknown command or command/argument pair: {name} {args!r}")

    mocked_ec = mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand)

    result = add_key_to_list_command(
        {"listName": MOCK_LIST_NAME, "keyName": MOCK_KEY_NAME, "value": MOCK_VALUE, "append": "true", "allowDups": "true"}
    )

    assert result.readable_output == f"Successfully updated list {MOCK_LIST_NAME}."
    assert len(mocked_ec.call_args_list) == 2
    assert mocked_ec.call_args_list[1][0][0] == "setList"
    assert json.loads(mocked_ec.call_args_list[1][0][1]["listData"]) == MOCKED_END_LIST