from unittest import mock from unittest.mock import MagicMock from unittest.mock import patch import boto3 import pytest from processing_accounting.util import dynamodb def test_get_expressions(monkeypatch): mock_kwargs = { 's3_path': 's3://test_bucket/test_prefix' } expressions = dynamodb._get_expressions('generating', **mock_kwargs) actual_update_expression = expressions[0] actual_expression_attribute_names = expressions[1] actual_expression_attribute_values = expressions[2] assert actual_update_expression == ( 'SET #status = :status,#s3_path = :s3_path') assert '#s3_path' in actual_expression_attribute_names assert actual_expression_attribute_names['#s3_path'] == ( 's3_path') assert ':s3_path' in actual_expression_attribute_values assert 'S' in actual_expression_attribute_values[':s3_path'] assert ':status' in actual_expression_attribute_values def test_set_status(monkeypatch): """test set status """ mock_resource = MagicMock() mock_table = MagicMock() monkeypatch.setattr( mock_resource, 'Table', MagicMock(return_value=mock_table)) monkeypatch.setattr( boto3, 'resource', MagicMock(return_value=mock_resource)) monkeypatch.setattr( mock_table, 'update_item', MagicMock(return_value=True)) mock_kwargs = { 's3_path': 's3://test_bucket/test_prefix' } dynamodb.set_status('99999L', '202,203,204', 'generating', **mock_kwargs) mock_table.update_item.assert_called_with( Key={ 'user_id_type': {'S': '99999L'}, 'user_params': {'S': '202,203,204'} }, UpdateExpression='SET #status = :status,#s3_path = :s3_path', ExpressionAttributeNames={'#status': 'status', '#s3_path': 's3_path'}, ExpressionAttributeValues={ ':status': {'S': 'generating'}, ':s3_path': {'S': 's3://test_bucket/test_prefix'} } ) @patch('processing_accounting.util.dynamodb.Attr') def test_scan_table_by_attribute_has_results(mock_attr, monkeypatch): """Test scan_table_by_attribute. """ mock_resource = MagicMock() mock_attr_obj = MagicMock() monkeypatch.setattr( mock_attr_obj, 'eq', MagicMock(return_value=True)) mock_table = MagicMock() mock_resultsets = {'Items': [{'fieldA', 'valueA'}, {'fieldB', 'valueB'}]} mock_attr.return_value = mock_attr_obj monkeypatch.setattr( mock_table, 'scan', MagicMock(return_value=mock_resultsets)) monkeypatch.setattr( mock_resource, 'Table', MagicMock(return_value=mock_table)) monkeypatch.setattr( boto3, 'resource', MagicMock(return_value=mock_resource)) resp = dynamodb.scan_table_by_attribute( user_id_type='18805L', status='PENDING') mock_table.scan.assert_any_call(FilterExpression=True) assert resp == [{'fieldA', 'valueA'}, {'fieldB', 'valueB'}] @patch('processing_accounting.util.dynamodb.Attr') def test_scan_table_by_attribute_no_results(mock_attr, monkeypatch): """Test scan_table_by_attribute. """ mock_resource = MagicMock() mock_attr_obj = MagicMock() mock_attr_obj.eq = lambda value: value mock_table = MagicMock() mock_resultsets = {} mock_attr.return_value = mock_attr_obj monkeypatch.setattr( mock_table, 'scan', MagicMock(return_value=mock_resultsets)) monkeypatch.setattr( mock_resource, 'Table', MagicMock(return_value=mock_table)) monkeypatch.setattr( boto3, 'resource', MagicMock(return_value=mock_resource)) dynamodb.scan_table_by_attribute(user_id_type=345, status=222) resp = mock_table.scan.assert_any_call(FilterExpression=345 & 222) assert not resp def test_delete_item_object(monkeypatch): """Test delete_item_object utility function.""" mock_resource = MagicMock() mock_table = MagicMock() monkeypatch.setattr( mock_resource, 'Table', MagicMock(return_value=mock_table)) monkeypatch.setattr( boto3, 'resource', MagicMock(return_value=mock_resource)) monkeypatch.setattr( mock_table, 'delete_item', MagicMock(return_value=True)) item = {'user_id_type': '18805L', 'status': 'PENDING'} dynamodb.delete_item_object(item) mock_table.delete_item.assert_called_with( Key={'user_id_type': '18805L'} ) @pytest.mark.parametrize('expected_status', ['TEST', 'GENERATING']) def test_get_status_using_session(expected_status): "Test get_status_using_session utility function." key = 'test_key' table_name = 'test_table_name' item = {'Item': {'status': expected_status}} session = mock.MagicMock() dynamodb_mock = mock.MagicMock() table = mock.MagicMock() session.resource.return_value = dynamodb_mock dynamodb_mock.Table.return_value = table table.get_item.return_value = item result = dynamodb.get_status_using_session(key, table_name, session) assert expected_status == result session.resource.assert_called_once_with('dynamodb') dynamodb_mock.Table.assert_called_once_with(table_name) table.get_item.assert_called_once_with(Key=key) @patch('processing_accounting.util.dynamodb.boto3') @pytest.mark.parametrize('input_data,expected', [ ( {'partition_key': 'user_id_type', 'partition_key_value': '123L', 'sort_key': 'collaborator_params', 'sort_key_value': '12345TEST', 'amount': 42, 'report_run_name': 'Test'}, {'user_id_type': '123L', 'collaborator_params': '12345TEST', 'amount': 42, 'report_run_name': 'Test'} ), ( {'partition_key': 'key', 'partition_key_value': 'value', 'thing': 1234, 'person': 'Test'}, {'key': 'value', 'thing': 1234, 'person': 'Test'} ) ]) def test_put_item(mock_boto3, input_data, expected): mock_dynamodb = MagicMock() mock_boto3.resource.return_value = mock_dynamodb mock_table = MagicMock() mock_dynamodb.Table.return_value = mock_table dynamodb.put_item(**input_data) mock_table.put_item.assert_called_with(Item=expected)