"""Lambda test module.""" import os from unittest.mock import patch from src.app import handler from src.app import BackupRecoveryInfo from src.app import find_resource import config @patch('src.app.get_info') @patch('src.app.start_recovery_job') @patch('src.app.delete_table') def test_handler(mock_delete_table, mock_start_recovery_job, mock_get_info, monkeypatch): """Test handler function.""" # Mocking the return value of get_info function monkeypatch.setattr(config, 'PROD_TABLE', 'arn:aws:dynamodb:us-east-1:123456789102:table/mock') mock_info = BackupRecoveryInfo( recovery_point_arn='arn:aws:backup:us-east-1:123456789102:recovery-point:01a643cd-f690-4ff1-b683-1edbc372ee78', backup_vault_status='COMPLETED', resource_arn='arn:aws:dynamodb:us-east-1:123456789102:table/mock', backup_vault_arn='arn:aws:backup:us-east-1:123456789102:backup-vault:mock-backup-vault' ) mock_get_info.return_value = mock_info mock_delete_table.return_value = True mock_start_recovery_job.return_value = {'status': 'OK'} result = handler({}, None) assert result == {'status': 'OK'} # Assert that functions were called with the expected args mock_get_info.assert_called_with(config.BACKUP_VAULT_NAME) mock_start_recovery_job.assert_called_with( mock_info.recovery_point_arn, config.REFRESH_TABLE_NAME, config.REFRESH_TABLE_KMS_KEY_ARN, config.REFRESH_IAM_ROLE ) mock_delete_table.assert_called_with(config.REFRESH_TABLE_NAME) @patch('src.app.find_resource') @patch('src.app.start_recovery_job') @patch('src.app.delete_table') def test_handler_with_source_name(mock_delete_table, mock_start_recovery_job, mock_find_resource, monkeypatch): """Test handler function with supplied source name.""" # Mocking the return value of find_resource function monkeypatch.setattr(config, 'PROD_TABLE', 'arn:aws:dynamodb:us-east-1:123456789102:table/mock') monkeypatch.setattr(config, 'SOURCE_NAME', 'mock') mock_resource = BackupRecoveryInfo( recovery_point_arn='arn:aws:backup:us-east-1:123456789102:recovery-point:01a643cd-f690-4ff1-b683-1edbc372ee78', backup_vault_status='COMPLETED', resource_arn='arn:aws:dynamodb:us-east-1:123456789102:table/mock', backup_vault_arn='arn:aws:backup:us-east-1:123456789102:backup-vault:mock-backup-vault' ) mock_find_resource.return_value = mock_resource mock_delete_table.return_value = True mock_start_recovery_job.return_value = {'status': 'OK'} result = handler({}, None) assert result == {'status': 'OK'} # Assert that functions were called with the expected args mock_find_resource.assert_called_with(config.BACKUP_VAULT_NAME, 'mock') mock_start_recovery_job.assert_called_with( mock_resource.recovery_point_arn, config.REFRESH_TABLE_NAME, config.REFRESH_TABLE_KMS_KEY_ARN, config.REFRESH_IAM_ROLE ) mock_delete_table.assert_called_with(config.REFRESH_TABLE_NAME) @patch('src.app.find_resource') @patch('src.app.start_recovery_job') @patch('src.app.delete_table') def test_handler_with_source_name_returns_none(mock_delete_table, mock_start_recovery_job, mock_find_resource, monkeypatch): """Test handler function when find_resource returns None.""" # Mocking the return value of find_resource function monkeypatch.setattr(config, 'PROD_TABLE', 'arn:aws:dynamodb:us-east-1:123456789102:table/mock') monkeypatch.setattr(config, 'SOURCE_NAME', 'mock') mock_find_resource.return_value = None mock_delete_table.return_value = True mock_start_recovery_job.return_value = {'status': 'OK'} try: handler({}, None) except Exception as e: assert str(e) == "'NoneType' object has no attribute 'recovery_point_arn'" mock_delete_table.assert_not_called() mock_start_recovery_job.assert_not_called() @patch('src.app.backup.list_recovery_points_by_backup_vault') def test_find_resource(mock_aws): """Test find_resource function when a matching resource is found.""" # Mocking the return value of aws calls call1 = { 'NextToken': 'string', 'RecoveryPoints': [ { 'Status': 'COMPLETED', 'ResourceName': 'string', 'ResourceArn': 'arn:aws:dynamodb:us-east-1:123456789102:table/needle', 'RecoveryPointArn': 'arn:aws:backup:us-east-1:123456789102:recovery-point:123', 'BackupVaultArn': 'arn:aws:backup:us-east-1:123456789102:backup-vault:mock-backup-vault' }, ] } call2 = { 'RecoveryPoints': [ { 'Status': 'COMPLETED', 'ResourceName': 'needle', 'ResourceArn': 'arn:aws:dynamodb:us-east-1:123456789102:table/needle', 'RecoveryPointArn': 'arn:aws:backup:us-east-1:123456789102:recovery-point:456', 'BackupVaultArn': 'arn:aws:backup:us-east-1:123456789102:backup-vault:mock-backup-vault' }, ] } mock_aws.side_effect = [call1, call2] resource = find_resource('mock-backup-vault', 'needle') assert mock_aws.call_count == 2 assert resource is not None assert resource.recovery_point_arn == 'arn:aws:backup:us-east-1:123456789102:recovery-point:456' assert resource.resource_arn == 'arn:aws:dynamodb:us-east-1:123456789102:table/needle' assert resource.backup_vault_arn == 'arn:aws:backup:us-east-1:123456789102:backup-vault:mock-backup-vault' assert resource.backup_vault_status == 'COMPLETED' @patch('src.app.backup.list_recovery_points_by_backup_vault') def test_find_resource_no_matching_resource(mock_aws): """Test find_resource function when no matching resource is found.""" # Mocking the return value of aws calls call1 = { 'NextToken': 'string', 'RecoveryPoints': [ { 'Status': 'COMPLETED', 'ResourceName': 'string', }, ] } call2 = { 'RecoveryPoints': [ { 'Status': 'COMPLETED', 'ResourceName': 'string', }, ] } mock_aws.side_effect = [call1, call2] resource = find_resource('mock-backup-vault', 'non-existent-source') assert mock_aws.call_count == 2 assert resource is None