"""Tests for sanitize utility.""" from unittest.mock import MagicMock, patch import pytest from lib.utils.aws import delete_files from lib.utils.aws import get_credentials_for_assumed_role from lib.utils.aws import get_ec2_client from lib.utils.aws import get_ecs_client from lib.utils.aws import get_file from lib.utils.aws import get_security_group from lib.utils.aws import get_sts_client from lib.utils.aws import get_subnet from lib.utils.aws import get_vpc from lib.utils.aws import read_key from lib.utils.aws import sanitize @pytest.fixture def mock_s3_hook(): """Do not actually make S3 calls.""" with patch('lib.utils.aws.S3Hook') as mock_hook_cls: mock_hook = MagicMock() mock_hook_cls.return_value = mock_hook yield mock_hook def test_read_key(mock_s3_hook): """Test contents of specified S3 bucket/key are read.""" mock_s3_hook.read_key.return_value = '{"amount":1234,"total_count":4567}' result = read_key(bucket_name='bucket_name', key='key') mock_s3_hook.read_key.assert_called_with('key', bucket_name='bucket_name') assert result == '{"amount":1234,"total_count":4567}' def test_sanitizing_a_string(): """Remove special characters and truncate to length 100.""" input_string = """ r-p-o-p-h-e-s-s-a-g-r who a)s w(e loo)k upnowgath PPEGORHRASS eringint(o- aThe):l eA !p: S a (r rIvInG .gRrEaPsPhOs) to rea(be)rran(com)gi(e)ngly ,grasshopper; """ assert sanitize(input_string) == \ 'r-p-o-p-h-e-s-s-a-g-r-who-a-s-w'\ '-e-loo-k-upnowgath-ppegorhrass-'\ 'eringint-o-athe-l-ea-p-s-a-r-ri'\ 'ving-gr' assert sanitize('No bye, no aloha', max_length=7) == 'no-bye' @patch('lib.utils.aws.S3Hook') def test_delete_files_single_file(mock_s3_hook): """Test deleting a single file from an S3 bucket.""" bucket = 'charlie' key = 'golden_ticket' mock_s3_hook.delete_objects.return_value = None delete_files(bucket, key) assert mock_s3_hook.delete_objects.called_once_with( bucket=bucket, key=key ) @patch('lib.utils.aws.S3Hook') def test_delete_files_list_of_files(mock_s3_hook): """Test deleting a list of files from an S3 bucket.""" bucket = 'charlie' keys = ['augustus', 'mike', 'veruca', 'violet'] mock_s3_hook.delete_objects.return_value = None delete_files(bucket=bucket, keys=keys) assert mock_s3_hook.delete_objects.called_once_with( bucket=bucket, keys=keys ) @patch('boto3.client') @patch('tempfile.NamedTemporaryFile') def test_get_file(mock_boto3_client, mock_named_temporary_file): """Test downloading a file from S3.""" mock_s3_client = mock_boto3_client('s3') mock_file = mock_named_temporary_file.return_value account_id = 'account_id' bucket = 'test_bucket' key = 'test/key.csv' file_path = '/test/file/path.csv' mock_file.name = '/test/file/path.csv' mock_s3_client.download_file.return_value = file_path response = get_file(account_id, bucket, key) assert response assert isinstance(response, str) assert response.endswith('.xlsx') @patch('boto3.client') def test_get_sts_client(mock_boto3_client): """Test getting STS client.""" mock_boto3_client.return_value = MagicMock() sts_client = get_sts_client() assert mock_boto3_client.called_once_with('sts') assert isinstance(sts_client, MagicMock) def test_get_credentials_for_assumed_role(): """Test getting credentials for an assumed role.""" mock_sts_client = MagicMock() mock_sts_client.assume_role.return_value = { 'Credentials': { 'AccessKeyId': 'test_access_key', 'SecretAccessKey': 'test_secret_key', 'SessionToken': 'test_session_token' } } credentials = get_credentials_for_assumed_role( mock_sts_client, role_arn='arn:aws:iam::123456789012:role/test-role', session_name='test_session' ) assert credentials['AccessKeyId'] == 'test_access_key' assert credentials['SecretAccessKey'] == 'test_secret_key' assert credentials['SessionToken'] == 'test_session_token' @patch('boto3.client') def test_get_ecs_client_with_creds(mock_boto3_client): """Test getting ECS client with credentials.""" mock_boto3_client.return_value = MagicMock() credentials = { 'AccessKeyId': 'test_access_key', 'SecretAccessKey': 'test_secret_key', 'SessionToken': 'test_session_token' } ecs_client = get_ecs_client(credentials) assert mock_boto3_client.called_once_with( 'ecs', aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'] ) assert isinstance(ecs_client, MagicMock) @patch('boto3.client') def test_get_ecs_client_without_creds(mock_boto3_client): """Test getting ECS client without credentials.""" mock_boto3_client.return_value = MagicMock() ecs_client = get_ecs_client() assert mock_boto3_client.called_once_with('ecs') assert isinstance(ecs_client, MagicMock) @patch('boto3.client') def test_get_ec2_client_with_creds(mock_boto3_client): """Test getting EC2 client with credentials.""" mock_boto3_client.return_value = MagicMock() credentials = { 'AccessKeyId': 'test_access_key', 'SecretAccessKey': 'test_secret_key', 'SessionToken': 'test_session_token' } ec2_client = get_ec2_client(credentials) assert mock_boto3_client.called_once_with( 'ec2', aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'] ) assert isinstance(ec2_client, MagicMock) @patch('boto3.client') def test_get_ec2_client_without_creds(mock_boto3_client): """Test getting EC2 client without credentials.""" mock_boto3_client.return_value = MagicMock() ec2_client = get_ec2_client() assert mock_boto3_client.called_once_with('ec2') assert isinstance(ec2_client, MagicMock) def test_get_vpc(): """Test getting VPC ID.""" mock_ec2_client = MagicMock() mock_ec2_client.describe_vpcs.return_value = { 'Vpcs': [{'VpcId': 'vpc-12345678'}] } vpc_id = get_vpc(mock_ec2_client) assert vpc_id == 'vpc-12345678' def test_get_security_group(): """Test getting security group.""" mock_ec2_client = MagicMock() mock_ec2_client.describe_security_groups.return_value = { 'SecurityGroups': [{'GroupId': 'sg-12345678'}] } vpc_id = 'vpc-12345678' service_name = 'test_service' security_group = get_security_group(mock_ec2_client, vpc_id, service_name) assert security_group == 'sg-12345678' def test_get_subnet(): """Test getting subnet.""" mock_ec2_client = MagicMock() mock_ec2_client.describe_subnets.return_value = { 'Subnets': [ {'SubnetId': 'subnet-12345678', 'AvailableIpAddressCount': 10}, {'SubnetId': 'subnet-87654321', 'AvailableIpAddressCount': 5}, {'SubnetId': 'subnet-11223344', 'AvailableIpAddressCount': 20} ] } vpc_id = 'vpc-12345678' subnet_id = get_subnet(mock_ec2_client, vpc_id) assert subnet_id == 'subnet-11223344'