# flake8: noqa """Test find_or_create_account handler.""" from unittest.mock import patch, ANY import pytest from common.schemas.state_machine_schema import StateMachineSchema from src import index from src.exceptions import ProductExistUnderDifferentVendorException, \ RetryableException, VendorDoNotIngestException, LambdaException @pytest.fixture def patched_modules(): """Patch the modules used in the handler.""" with ( patch('src.index.logger') as mock_logger, patch( 'src.index.check_remapping_parent_rep_owner') as mock_check_remapping_parent_rep_owner, patch( 'src.index.insert_vendor_and_subaccount_mapping') as mock_insert_vendor_and_subaccount_mapping, patch( 'src.index.get_vendor_via_graphql') as mock_get_vendor_via_graphql, patch( 'src.index.get_subaccount_via_graphql') as mock_get_subaccount_via_graphql, patch( 'src.index.get_vendor_and_subaccount_in_mapping_table') as mock_get_vendor_and_subaccount_in_mapping_table, patch('src.index.get_vendor_and_subaccount_for_existing_product') as mock_get_vendor_and_subaccount_for_existing_product, patch('src.index.create_vendor') as mock_create_vendor, patch('src.index.create_subaccount') as mock_create_subaccount, ): yield { 'logger': mock_logger, 'check_remapping_parent_rep_owner': mock_check_remapping_parent_rep_owner, 'insert_vendor_and_subaccount_mapping': mock_insert_vendor_and_subaccount_mapping, 'get_vendor_via_graphql': mock_get_vendor_via_graphql, 'get_subaccount_via_graphql': mock_get_subaccount_via_graphql, 'get_vendor_and_subaccount_in_mapping_table': mock_get_vendor_and_subaccount_in_mapping_table, 'get_vendor_and_subaccount_for_existing_product': mock_get_vendor_and_subaccount_for_existing_product, 'create_vendor': mock_create_vendor, 'create_subaccount': mock_create_subaccount, } def test_handler_get_vendor_and_subaccount_for_existing_product( patched_modules, mock_event): """Test handler with mapping in mapping table.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].return_value = (123, 345) # Call the handler result = index.handler(mock_event, None) # Assertions patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].assert_not_called() patched_modules['get_vendor_via_graphql'].assert_not_called() patched_modules['insert_vendor_and_subaccount_mapping'].assert_not_called() patched_modules['create_vendor'].assert_not_called() assert result['product']['vendor_id'] == 123 assert result['product']['subaccount_id'] == 345 assert result['product']['not_for_distribution'] == 'SMEAnalyticsDummy' # def test_handler_get_vendor_and_subaccount_for_existing_product_raises_error( patched_modules, mock_event): """Test handler with mapping in mapping table.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].side_effect = ( ProductExistUnderDifferentVendorException( 'Product exists under different vendor')) # Call the handler with pytest.raises(ProductExistUnderDifferentVendorException): index.handler(mock_event, None) # Assertions patched_modules['check_remapping_parent_rep_owner'].assert_not_called() patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].assert_not_called() patched_modules['get_vendor_via_graphql'].assert_not_called() patched_modules['insert_vendor_and_subaccount_mapping'].assert_not_called() patched_modules['create_vendor'].assert_not_called() def test_handler_with_mapping_in_the_mapping_table( patched_modules, mock_event): """Test handler with mapping in mapping table.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].return_value = (None, None) patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].return_value = (123, 345) # Call the handler result = index.handler(mock_event, None) # Assertions patched_modules['get_vendor_via_graphql'].assert_not_called() patched_modules['insert_vendor_and_subaccount_mapping'].assert_not_called() patched_modules['create_vendor'].assert_not_called() assert result['product']['vendor_id'] == 123 assert result['product']['subaccount_id'] == 345 assert result['product']['not_for_distribution'] == 'SMEAnalyticsDummy' def test_handler_without_mapping_the_mapping_table( patched_modules, mock_event): """Test handler without mapping in table, but there is mapping via graphql.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].return_value = (None, None) patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].return_value = (None, None) patched_modules['get_vendor_via_graphql'].return_value = 123 patched_modules['get_subaccount_via_graphql'].return_value = 345 # Call the handler result = index.handler(mock_event, None) # Assertions patched_modules['get_subaccount_via_graphql'].assert_called_once_with( ANY, 123) patched_modules[ 'insert_vendor_and_subaccount_mapping'].assert_called_once_with( patched_modules['logger'], 123, 345, ANY) patched_modules['create_vendor'].assert_not_called() assert result['product']['vendor_id'] == 123 assert result['product']['subaccount_id'] == 345 assert result['product']['not_for_distribution'] == 'SMEAnalyticsDummy' def test_handler_without_vendor_via_graphql(patched_modules, mock_event): """Test handler without mapping in table and via graphql.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].return_value = (None, None) patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].return_value = (None, None) patched_modules['get_vendor_via_graphql'].return_value = None patched_modules['create_vendor'].return_value = 123 patched_modules['create_subaccount'].return_value = 345 # Call the handler result = index.handler(mock_event, None) # Assertions patched_modules['get_subaccount_via_graphql'].assert_not_called() patched_modules[ 'insert_vendor_and_subaccount_mapping'].assert_called_once_with( patched_modules['logger'], 123, 345, ANY) patched_modules['create_subaccount'].assert_called_once_with(ANY, 123) assert result['product']['vendor_id'] == 123 assert result['product']['subaccount_id'] == 345 assert result['product']['not_for_distribution'] == 'SMEAnalyticsDummy' # # def test_handler_without_subaccount_via_graphql(patched_modules, mock_event): """Test handler without mapping in table, there is vendor, but no subaccount.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].return_value = (None, None) patched_modules[ 'get_vendor_and_subaccount_in_mapping_table'].return_value = (None, None) patched_modules['get_vendor_via_graphql'].return_value = 123 patched_modules['get_subaccount_via_graphql'].return_value = None patched_modules['create_subaccount'].return_value = 345 # Call the handler result = index.handler(mock_event, None) # Assertions patched_modules['get_subaccount_via_graphql'].assert_called_once_with(ANY, 123) patched_modules[ 'insert_vendor_and_subaccount_mapping'].assert_called_once_with( patched_modules['logger'], 123, 345, ANY) patched_modules['create_vendor'].assert_not_called() patched_modules['create_subaccount'].assert_called_once_with(ANY, 123) assert result['product']['vendor_id'] == 123 assert result['product']['subaccount_id'] == 345 assert result['product']['not_for_distribution'] == 'SMEAnalyticsDummy' @pytest.mark.parametrize('exception', [ (TimeoutError('The read operation timed out')), (ConnectionError('The connection timed out')) ]) def test_handler_raises_retry_error(patched_modules, mock_event, exception): """Test handler raises RetryableException for specific errors.""" patched_modules[ 'get_vendor_and_subaccount_for_existing_product'].side_effect = exception # Call the handler with pytest.raises(RetryableException): index.handler(mock_event, None) @patch('src.index.logger') @patch('src.index.get_vendor_and_subaccount_for_rep_owner_code_rows') def test_get_vendor_and_subaccount_in_mapping_table( mock_get_vendor_and_subaccount, mock_logger, mock_event): """Test get_vendor_and_subaccount with existing mapping.""" mock_get_vendor_and_subaccount.return_value = [ {'vendor_id': 123, 'subaccount_id': 345, 'do_not_ingest': False}] context = StateMachineSchema().load(mock_event) context.product.imprint = 'foo' # Call the function result = index.get_vendor_and_subaccount_in_mapping_table(context) # Assertions assert result == (123, 345) mock_get_vendor_and_subaccount.assert_called_once_with(mock_logger, context) @patch('src.index.logger') @patch('src.index.get_vendor_and_subaccount_for_rep_owner_code_rows') def test_get_vendor_and_subaccount_in_mapping_table_do_not_ingest( mock_get_vendor_and_subaccount, mock_logger, mock_event): """Test get_vendor_and_subaccount with existing mapping.""" mock_get_vendor_and_subaccount.return_value = [ {'vendor_id': 123, 'subaccount_id': 345, 'do_not_ingest': True}] context = StateMachineSchema().load(mock_event) context.product.imprint = 'foo' # Call the function with pytest.raises(VendorDoNotIngestException): index.get_vendor_and_subaccount_in_mapping_table(context) # Assertions mock_get_vendor_and_subaccount.assert_called_once_with(mock_logger, context) @patch('src.index.logger') @patch('src.index.get_vendor_and_subaccount_for_rep_owner_code_rows') def test_get_vendor_and_subaccount_in_mapping_table_no_mapping( mock_get_vendor_and_subaccount, mock_logger, mock_event): """Test get_vendor_and_subaccount if there is no mapping.""" mock_get_vendor_and_subaccount.return_value = [] # Call the function response = index.get_vendor_and_subaccount_in_mapping_table(mock_event) assert response == (None, None) # Assertions mock_get_vendor_and_subaccount.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_vendor_and_subaccount_for_rep_owner_code_rows') def test_get_vendor_and_subaccount_in_mapping_table_two_mappings( mock_get_vendor_and_subaccount, mock_logger, mock_event): """Test get_vendor_and_subaccount if there are more than one mapping.""" mock_get_vendor_and_subaccount.return_value = [ {'vendor_id': 123, 'subaccount_id': 345, 'do_not_ingest': False}, {'vendor_id': 456, 'subaccount_id': 789, 'do_not_ingest': False}] # Call the function with pytest.raises(LambdaException): index.get_vendor_and_subaccount_in_mapping_table(mock_event) # Assertions mock_get_vendor_and_subaccount.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_vendor_and_subaccount_for_rep_owner_code_rows') @pytest.mark.parametrize( 'imprint', [ 'Palm Tree Records/RCA Records', 'Palm Tree Records', ] ) def test_get_vendor_and_subaccount_in_mapping_table_palm_tree_records( mock_get_vendor_and_subaccount, mock_logger, mock_event, imprint): """Test get_vendor_and_subaccount if there palm_tree_records labels.""" mock_get_vendor_and_subaccount.return_value = [ {'vendor_id': 99, 'subaccount_id': 88, 'do_not_ingest': True}] context = StateMachineSchema().load(mock_event) context.product.imprint = imprint # Call the function result = index.get_vendor_and_subaccount_in_mapping_table(context) # Assertions assert result == (99, 88) mock_get_vendor_and_subaccount.assert_called_once_with(mock_logger, context) @patch('src.index.logger') @patch('src.index.get_vendor_for_rep_owner_code') def test_get_vendor_via_graphql( mock_get_vendor_for_rep_owner_code, mock_logger, mock_event): """Test get_vendor_via_graphql with existing vendor.""" mock_get_vendor_for_rep_owner_code.return_value = [ {'vendorId': 123}] # Call the function result = index.get_vendor_via_graphql(mock_event) # Assertions assert result == 123 mock_get_vendor_for_rep_owner_code.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_vendor_for_rep_owner_code') def test_get_vendor_via_graphql_no_mapping( mock_get_vendor_for_rep_owner_code, mock_logger, mock_event): """Test get_vendor_via_graphql if there is no mapping.""" mock_get_vendor_for_rep_owner_code.return_value = [] # Call the function response = index.get_vendor_via_graphql(mock_event) assert response is None # Assertions mock_get_vendor_for_rep_owner_code.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_vendor_for_rep_owner_code') def test_get_vendor_via_graphql_two_mappings( mock_get_vendor_for_rep_owner_code, mock_logger, mock_event): """Test get_vendor_via_graphql if there are more than one mapping.""" mock_get_vendor_for_rep_owner_code.return_value = [ {'vendorId': 123}, {'vendorId': 456}] # Call the function with pytest.raises(LambdaException): index.get_vendor_via_graphql(mock_event) # Assertions mock_get_vendor_for_rep_owner_code.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_subaccount_for_vendor') def test_get_subaccount_via_graphql( mock_get_subaccount_for_vendor, mock_logger, mock_event): """Test get_subaccount_via_graphql with existing subaccount.""" mock_get_subaccount_for_vendor.return_value = [{ 'name': 'Subaccount Name', 'subaccountId': 1212}] # Call the function result = index.get_subaccount_via_graphql(mock_event, 123) # Assertions assert result == 1212 mock_get_subaccount_for_vendor.assert_called_once_with(mock_logger, mock_event, 123) @patch('src.index.logger') @patch('src.index.get_subaccount_for_vendor') def test_get_subaccount_via_graphql_no_mapping( mock_get_subaccount_for_vendor, mock_logger, mock_event): """Test get_subaccount_via_graphql if there is no subaccount.""" mock_get_subaccount_for_vendor.return_value = [] # Call the function response = index.get_subaccount_via_graphql(mock_event, 123) assert response is None # Assertions mock_get_subaccount_for_vendor.assert_called_once_with(mock_logger, mock_event, 123) @patch('src.index.logger') @patch('src.index.get_subaccount_for_vendor') def test_get_subaccount_via_graphql_two_mappings( mock_get_subaccount_for_vendor, mock_logger, mock_event): """Test get_subaccount_via_graphql if there are more than one mapping.""" mock_get_subaccount_for_vendor.return_value = [{ 'name': 'Subaccount Name', 'subaccountId': 1212}, {'name': 'Subaccount Name2', 'subaccountId': 1213}] # Call the function with pytest.raises(LambdaException): index.get_subaccount_via_graphql(mock_event, 123) # Assertions mock_get_subaccount_for_vendor.assert_called_once_with(mock_logger, mock_event, 123) @patch('src.index.logger') @patch('src.index.get_product_by_upc') def test_get_vendor_and_subaccount_for_existing_product( mock_get_product_by_upc, mock_logger, mock_event): """Test get_product_by_upc with existing product.""" mock_get_product_by_upc.return_value = { 'vendorId': 123, 'subaccountId': 345, 'notForDistribution': 'SMEAnalyticsDummy' } # Call the function result = index.get_vendor_and_subaccount_for_existing_product(mock_event) # Assertions assert result == (123, 345) mock_get_product_by_upc.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_product_by_upc') def test_get_vendor_and_subaccount_for_existing_product_return_nothing( mock_get_product_by_upc, mock_logger, mock_event): """Test get_product_by_upc with existing product.""" mock_get_product_by_upc.return_value = None # Call the function result = index.get_vendor_and_subaccount_for_existing_product(mock_event) # Assertions assert result == (None, None) mock_get_product_by_upc.assert_called_once_with(mock_logger, mock_event) @patch('src.index.logger') @patch('src.index.get_product_by_upc') def test_get_vendor_and_subaccount_for_existing_product_error( mock_get_product_by_upc, mock_logger, mock_event): """Test get_product_by_upc with existing product.""" context = StateMachineSchema().load(mock_event) mock_get_product_by_upc.return_value = { 'vendorId': 123, 'subaccountId': 345, 'notForDistribution': 'N' } # Call the function with pytest.raises(ProductExistUnderDifferentVendorException): index.get_vendor_and_subaccount_for_existing_product(context) # Assertions mock_get_product_by_upc.assert_called_once_with(mock_logger, context) @patch('src.index.logger') @patch('src.index.get_parent_repertoire_owner_mapping') def test_check_remapping_parent_rep_owner_no_mapping(mock_get_mapping, mock_logger, mock_event): """Test check_remapping_parent_rep_owner with no mappings.""" mock_get_mapping.return_value = [] context = StateMachineSchema().load(mock_event) parent_repertoire_owner_code = context.product.parent_repertoire_owner_code # Call the function index.check_remapping_parent_rep_owner(context) # Assertions mock_get_mapping.assert_called_once_with(mock_logger, context) assert context.product.parent_repertoire_owner_code == parent_repertoire_owner_code @patch('src.index.logger') @patch('src.index.get_parent_repertoire_owner_mapping') def test_check_remapping_parent_rep_owner_single_mapping(mock_get_mapping, mock_logger, mock_event): """Test check_remapping_parent_rep_owner with a single mapping.""" mock_get_mapping.return_value = [{ 'REP_OWNER_PARENT_CD': 'NEW_CODE', 'REP_OWNER_PARENT_NM': 'New Name' }] context = StateMachineSchema().load(mock_event) context.product.parent_repertoire_owner_code = 'OLD_CODE' # Call the function index.check_remapping_parent_rep_owner(context) # Assertions mock_get_mapping.assert_called_once_with(mock_logger, context) assert context.product.parent_repertoire_owner_code == 'NEW_CODE' @patch('src.index.logger') @patch('src.index.get_parent_repertoire_owner_mapping') def test_check_remapping_parent_rep_owner_multiple_mappings(mock_get_mapping, mock_logger, mock_event): """Test check_remapping_parent_rep_owner with multiple mappings.""" mock_get_mapping.return_value = [ {'REP_OWNER_PARENT_CD': 'CODE1', 'REP_OWNER_PARENT_NM': 'Name1'}, {'REP_OWNER_PARENT_CD': 'CODE2', 'REP_OWNER_PARENT_NM': 'Name2'} ] context = StateMachineSchema().load(mock_event) # Call the function and assert exception with pytest.raises(LambdaException): index.check_remapping_parent_rep_owner(context) # Assertions mock_get_mapping.assert_called_once_with(mock_logger, context) @patch('src.index.logger') @patch('src.index.create_new_vendor') @patch('src.index.update_external_identifier_1') @patch('src.index.get_vendor_country_id') @patch('src.index.update_vendor_country_id') def test_create_vendor_success(mock_update_vendor_country_id, mock_get_vendor_country_id, mock_update_external_identifier_1, mock_create_new_vendor, mock_logger, mock_event): """Test create_vendor with successful vendor creation.""" # Mock the return value of create_new_vendor mock_create_new_vendor.return_value = {'vendorId': 123, 'uuid': 'uuid-123'} mock_get_vendor_country_id.return_value = 5 # Call the function result = index.create_vendor(mock_event) # Assertions assert result == 123 mock_create_new_vendor.assert_called_once_with(mock_logger, mock_event) mock_update_external_identifier_1.assert_called_once_with(mock_logger, mock_event, 'uuid-123') mock_update_vendor_country_id.assert_called_once_with(mock_logger, 5, 'uuid-123') @patch('src.index.logger') @patch('src.index.create_new_vendor') @patch('src.index.update_external_identifier_1') @patch('src.index.get_vendor_country_id') def test_create_vendor_failure(mock_get_vendor_country_id, mock_update_external_identifier_1, mock_create_new_vendor, mock_logger, mock_event): """Test create_vendor when vendor creation fails.""" # Mock the return value of create_new_vendor to None mock_create_new_vendor.return_value = None # Call the function and assert exception with pytest.raises(LambdaException, match='Vendor creation failed.'): index.create_vendor(mock_event) # Assertions mock_create_new_vendor.assert_called_once_with(mock_logger, mock_event) mock_get_vendor_country_id.assert_called_once_with(mock_event) mock_update_external_identifier_1.assert_not_called() @patch('src.index.logger') @patch('src.index.create_new_subaccount') def test_create_subaccount_success(mock_create_new_subaccount, mock_logger, mock_event): """Test create_subaccount with successful subaccount creation.""" # Mock the return value of create_new_subaccount mock_create_new_subaccount.return_value = {'subaccountId': 345} # Call the function result = index.create_subaccount(mock_event, 123) # Assertions assert result == 345 mock_create_new_subaccount.assert_called_once_with(mock_logger, mock_event, 123) @patch('src.index.logger') @patch('src.index.create_new_subaccount') def test_create_subaccount_failure(mock_create_new_subaccount, mock_logger, mock_event): """Test create_subaccount when subaccount creation fails.""" # Mock the return value of create_new_subaccount to None mock_create_new_subaccount.return_value = None # Call the function and assert exception with pytest.raises(LambdaException, match='Subaccount creation failed.'): index.create_subaccount(mock_event, 123) # Assertions mock_create_new_subaccount.assert_called_once_with(mock_logger, mock_event, 123)