def test_dynamodb_provider_get_multiple(mock_name, mock_value, config):
    """
    Test DynamoDBProvider.get_multiple() with a non-cached path
    """

    mock_param_names = ["A", "B", "C"]
    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {
        "Items": [
            {"id": {"S": mock_name}, "sk": {"S": name}, "value": {"S": f"{mock_value}/{name}"}}
            for name in mock_param_names
        ]
    }
    expected_params = {"TableName": table_name, "KeyConditionExpression": Key("id").eq(mock_name)}
    stubber.add_response("query", response, expected_params)
    stubber.activate()

    try:
        values = provider.get_multiple(mock_name)

        stubber.assert_no_pending_responses()

        assert len(values) == len(mock_param_names)
        for name in mock_param_names:
            assert name in values
            assert values[name] == f"{mock_value}/{name}"
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_default_config(monkeypatch, mock_name, mock_value):
    """
    Test DynamoDBProvider.get() without setting a config
    """

    monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")

    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name)

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {"Item": {"id": {"S": mock_name}, "value": {"S": mock_value}}}
    expected_params = {"TableName": table_name, "Key": {"id": mock_name}}
    stubber.add_response("get_item", response, expected_params)
    stubber.activate()

    try:
        value = provider.get(mock_name)

        assert value == mock_value
        stubber.assert_no_pending_responses()
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_expired(mock_name, mock_value, config):
    """
    Test DynamoDBProvider.get() with a cached but expired value
    """

    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Inject value in the internal store
    provider.store[(mock_name, None)] = ExpirableValue(mock_value, datetime.now() - timedelta(seconds=60))

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {"Item": {"id": {"S": mock_name}, "value": {"S": mock_value}}}
    expected_params = {"TableName": table_name, "Key": {"id": mock_name}}
    stubber.add_response("get_item", response, expected_params)
    stubber.activate()

    try:
        value = provider.get(mock_name)

        assert value == mock_value
        stubber.assert_no_pending_responses()
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_cached(mock_name, mock_value, config):
    """
    Test DynamoDBProvider.get() with a cached value
    """

    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Inject value in the internal store
    provider.store[(mock_name, None)] = ExpirableValue(
        mock_value,
        datetime.now() + timedelta(seconds=60))

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    stubber.activate()

    try:
        value = provider.get(mock_name)

        assert value == mock_value
        stubber.assert_no_pending_responses()
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_sdk_options_overwrite(mock_name, mock_value,
                                                     config):
    """
    Test DynamoDBProvider.get() with SDK options that should be overwritten
    """

    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {"Item": {"id": {"S": mock_name}, "value": {"S": mock_value}}}
    expected_params = {"TableName": table_name, "Key": {"id": mock_name}}
    stubber.add_response("get_item", response, expected_params)
    stubber.activate()

    try:
        value = provider.get(mock_name, Key="THIS_SHOULD_BE_OVERWRITTEN")

        assert value == mock_value
        stubber.assert_no_pending_responses()
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_sdk_options(mock_name, mock_value, config):
    """
    Test DynamoDBProvider.get() with SDK options
    """

    table_name = "TEST_TABLE"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {"Item": {"id": {"S": mock_name}, "value": {"S": mock_value}}}
    expected_params = {
        "TableName": table_name,
        "Key": {
            "id": mock_name
        },
        "ConsistentRead": True
    }
    stubber.add_response("get_item", response, expected_params)
    stubber.activate()

    try:
        value = provider.get(mock_name, ConsistentRead=True)

        assert value == mock_value
        stubber.assert_no_pending_responses()
    finally:
        stubber.deactivate()
def test_dynamodb_provider_get_multiple_auto(mock_name, mock_value, config):
    """
    Test DynamoDBProvider.get_multiple() with transform = "auto"
    """
    mock_binary = mock_value.encode()
    mock_binary_data = base64.b64encode(mock_binary).decode()
    mock_json_data = json.dumps({mock_name: mock_value})
    mock_params = {"D.json": mock_json_data, "E.binary": mock_binary_data, "F": mock_value}
    table_name = "TEST_TABLE_AUTO"

    # Create a new provider
    provider = parameters.DynamoDBProvider(table_name, config=config)

    # Stub the boto3 client
    stubber = stub.Stubber(provider.table.meta.client)
    response = {
        "Items": [
            {"id": {"S": mock_name}, "sk": {"S": name}, "value": {"S": value}} for (name, value) in mock_params.items()
        ]
    }
    expected_params = {"TableName": table_name, "KeyConditionExpression": Key("id").eq(mock_name)}
    stubber.add_response("query", response, expected_params)
    stubber.activate()

    try:
        values = provider.get_multiple(mock_name, transform="auto")

        stubber.assert_no_pending_responses()

        assert len(values) == len(mock_params)
        for key in mock_params.keys():
            assert key in values
            if key.endswith(".json"):
                assert values[key][mock_name] == mock_value
            elif key.endswith(".binary"):
                assert values[key] == mock_binary
            else:
                assert values[key] == mock_value
    finally:
        stubber.deactivate()