"""Unit testcases for TerritoryBackfill processor.""" from datetime import datetime from unittest.mock import call from unittest.mock import MagicMock from unittest.mock import patch from royalty_collection_territory_backfill.constants.constants import \ WORLDWIDE_TERRITORIES_IDS from royalty_collection_territory_backfill.processor import \ TerritoryBackfillProcessor def test__get_and_format_countries_from_ar_db(): """Test _get_and_format_countries_from_ar_db method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.fetchall.return_value = [{ 'iso3166a3': 'USA', 'id': 1 }, { 'iso3166a3': 'CAN', 'id': 2 }] mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._get_and_format_countries_from_ar_db() assert result == {'USA': '1', 'CAN': '2'} mock_cursor.execute.assert_called_once_with( 'SELECT\n iso3166a3,\n id\nFROM country;' ) def test__get_abacus_accounts(): """Test _get_abacus_accounts method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.fetchall.return_value = [ {'account_id': '1'}, {'account_id': '2'} ] mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._get_abacus_accounts() assert result == ['1', '2'] mock_cursor.execute.assert_called_once_with( 'SELECT account_id FROM account;' ) def test__batch_account_ids(): """Test _batch_account_ids method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = ['1', '2', '3', '4'] with patch( 'royalty_collection_territory_backfill.processor.ACCOUNT_BATCH_SIZE', '2' ): result = territoryBackfill._batch_account_ids(account_ids) assert result == [['1', '2'], ['3', '4']] def test__create_temp_table_in_art_relations(): """Test _create_temp_table_in_art_relations method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._create_temp_table_in_art_relations() assert result is True mock_cursor.execute.assert_called_once_with( 'CREATE TEMPORARY TABLE temp_collection_territories (\n account_id INT PRIMARY KEY,\n territory TEXT NOT NULL\n);' # noqa: E501 ) mock_ar_mysql_conn.commit.assert_called_once() def test__get_abacus_accounts_and_their_territories(): """Test _get_abacus_accounts_and_their_territories method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() expected_response = [ {'account_id': '1', 'country_codes': 'USA,AUS,IND'}, {'account_id': '2', 'country_codes': None} ] mock_cursor.fetchall.return_value = expected_response mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = ['1', '2'] result = territoryBackfill._get_abacus_accounts_and_their_territories( account_ids ) assert result == expected_response assert mock_cursor.execute.call_count == 2 def test__format_account_and_territories_data(): """Test _format_account_and_territories_data method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) accounts_and_territories = [ {'account_id': '1', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '2', 'country_codes': None} ] with patch.object( territoryBackfill, '_TerritoryBackfillProcessor__countries', {'USA': '1', 'CAN': '2', 'AUS': '3'} ): result = territoryBackfill._format_account_and_territories_data( accounts_and_territories ) assert result == [('1', '1,2,3'), ('2', ','.join(WORLDWIDE_TERRITORIES_IDS))] def test__insert_into_temp_table(): """Test _insert_into_temp_table method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) insertion_data = [('1', '1,2,3'), ('2', '1,2')] result = territoryBackfill._insert_into_temp_table(insertion_data) assert result is True mock_cursor.executemany.assert_called_once_with( 'INSERT INTO temp_collection_territories (account_id, territory) VALUES (%s, %s);', [('1', '1,2,3'), ('2', '1,2')] # noqa: E501 ) mock_ar_mysql_conn.commit.assert_called_once() def test__update_vendor_contract_and_history_table(): """Test _update_vendor_contract_and_history_table method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True mock_cursor.fetchall.return_value = [{ 'vendor_id': '1', 'vendor_contract_id': '1' }, { 'vendor_id': '2', 'vendor_contract_id': '2' }] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._update_vendor_contract_and_history_table() assert result == ['1', '2'] assert mock_cursor.execute.call_count == 3 mock_ar_mysql_conn.commit.assert_called_once() def test__update_vendor_contract_and_history_table_no_data(): """Test _update_vendor_contract_and_history_table method. When there is no data to update. """ mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True mock_cursor.fetchall.return_value = [] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._update_vendor_contract_and_history_table() assert result == [] assert mock_cursor.execute.call_count == 1 mock_ar_mysql_conn.commit.assert_not_called() def test__render_sql_template(): """Test _render_sql_template method.""" mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._render_sql_template('abacus/get_accounts.sql') assert result == 'SELECT account_id FROM account;' @patch('royalty_collection_territory_backfill.processor.SlackClient') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__notify_success_message_no_data_dev_env(mock_logger, mock_slack_client): """Test _notify_success_message" method for dev env. When there is no data to update. """ mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_slack_client.return_value.post_block_message.return_value = False mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = [] territoryBackfill._notify_success_message(account_ids) mock_logger.assert_called_once_with('No data available for sync.') mock_slack_client.return_value.post_block_message.assert_not_called() @patch('royalty_collection_territory_backfill.processor.SlackClient') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__notify_success_message_dev_env(mock_logger, mock_slack_client): """Test _notify_success_message" method for dev env.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_slack_client.return_value.post_block_message.return_value = False mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = ['1', '2', '3'] territoryBackfill._notify_success_message(account_ids) mock_logger.assert_has_calls([ call('The automated process updated 3 accounts.'), call('Processed Accounts: 1,2,3') ]) mock_slack_client.return_value.post_block_message.assert_not_called() @patch('royalty_collection_territory_backfill.processor.SlackClient') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__notify_success_message_qa_env(mock_logger, mock_slack_client): """Test _notify_success_message" method for qa env.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_slack_client.return_value.post_block_message.return_value = True mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = ['1', '2', '3'] with patch.multiple( 'royalty_collection_territory_backfill.processor', ENVIRONMENT='qa', CHANNEL_ID='1234' ): territoryBackfill._notify_success_message(account_ids) payload = [ { 'type': 'section', 'text': { 'type': 'mrkdwn', 'text': '*:white_check_mark: Royalty Territory Sync Successful!* :arrows_counterclockwise:\n' # noqa: E501 } }, { 'type': 'section', 'text': { 'type': 'plain_text', 'text': 'The automated process updated 3 accounts.\n' } } ] mock_logger.assert_called_once_with('Processed Accounts: 1,2,3') mock_slack_client.return_value.post_block_message.assert_called_once_with( '1234', payload, 'Sync Report' ) @patch('royalty_collection_territory_backfill.processor.SlackClient') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__notify_success_message_qa_env_no_data(mock_logger, mock_slack_client): """Test _notify_success_message" method for qa env. When there is no data to sync. """ mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_slack_client.return_value.post_block_message.return_value = True mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) account_ids = [] with patch.multiple( 'royalty_collection_territory_backfill.processor', ENVIRONMENT='qa', CHANNEL_ID='1234' ): territoryBackfill._notify_success_message(account_ids) payload = [{ 'type': 'section', 'text': { 'type': 'plain_text', 'text': 'No data available for sync.\n' } }] mock_logger.assert_not_called() mock_slack_client.return_value.post_block_message.assert_called_once_with( '1234', payload, 'Sync Report' ) def test___save_backfilled_account_list(): """Test _save_backfilled_account_list method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_abacus_mysql_conn.commit.return_value = True account_ids = ['1', '2', '3'] mock_cursor.fetchall.return_value = [{ 'vendor_id': '1', 'vendor_contract_id': '1' }, { 'vendor_id': '2', 'vendor_contract_id': '2' }] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._save_backfilled_account_list(account_ids) assert result is True assert mock_cursor.execute.assert_called_once mock_abacus_mysql_conn.commit.assert_called_once() @patch('royalty_collection_territory_backfill.processor.datetime') @patch('royalty_collection_territory_backfill.processor.SlackClient') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__send_file_to_slack(mock_logger, mock_slack_client, mock_datetime): """Test _send_file_to_slack" method for qa env.""" mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() fixed_dt = datetime(2025, 9, 17, 12, 34, 56) mock_datetime.now.return_value = fixed_dt mock_datetime.strftime = datetime.strftime mock_slack_client.return_value.file_upload.return_value = True account_ids = ['1', '2', '3'] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) with patch.multiple( 'royalty_collection_territory_backfill.processor', CHANNEL_ID='1234' ): territoryBackfill._send_file_to_slack(account_ids) mock_logger.assert_called_once_with( 'Writing accounts to text file and send it to slack.' ) mock_slack_client.return_value.file_upload.assert_called_once_with( '1234', '/tmp/processed_accounts_2025-09-17_12-34-56.txt', 'Processed accounts 📄', 'Sync Report' ) @patch('royalty_collection_territory_backfill.processor.TerritoryBackfillProcessor' '._get_invalid_territories_accounts_from_art_relation') @patch('royalty_collection_territory_backfill.processor' '.TerritoryBackfillProcessor._get_deleted_abacus_contract_term_accounts') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__cleanup_invalid_territories( mock_logger, mock_get_deleted_accounts, mock_get_invalid_territories ): """Test _cleanup_invalid_territories method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.rowcount = 5 mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True mock_get_deleted_accounts.return_value = [1, 2, 3, 4] mock_get_invalid_territories.return_value = [1, 2, 3, 4] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._cleanup_invalid_territories() assert result == [1, 2, 3, 4] mock_get_deleted_accounts.assert_called_once() assert mock_cursor.execute.call_count == 1 mock_ar_mysql_conn.commit.assert_called_once() mock_logger.assert_has_calls([ call( 'Cleaning up territories for accounts with no relevant' + ' performance rights transaction types contract terms.' ), call( 'Updated 5 vendor contracts to' + ' remove royalty collection territories as' + ' they no longer contain performance rights transaction types.' ) ]) @patch('royalty_collection_territory_backfill.processor.TerritoryBackfillProcessor' '._get_invalid_territories_accounts_from_art_relation') @patch('royalty_collection_territory_backfill.processor' '.TerritoryBackfillProcessor._get_deleted_abacus_contract_term_accounts') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__cleanup_invalid_territories_no_accounts_found( mock_logger, mock_get_deleted_accounts, mock_get_invalid_territories ): """Test _cleanup_invalid_territories method when there are no accounts with removed txn types.""" # noqa: E501 mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.rowcount = 5 mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True mock_get_deleted_accounts.return_value = [] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._cleanup_invalid_territories() assert result is None mock_get_deleted_accounts.assert_called_once() mock_get_invalid_territories.assert_not_called() assert mock_cursor.execute.call_count == 0 mock_ar_mysql_conn.commit.assert_not_called() mock_logger.assert_has_calls([ call( 'Cleaning up territories for accounts with no relevant' + ' performance rights transaction types contract terms.' ) ]) @patch('royalty_collection_territory_backfill.processor.TerritoryBackfillProcessor' '._get_invalid_territories_accounts_from_art_relation') @patch('royalty_collection_territory_backfill.processor' '.TerritoryBackfillProcessor._get_deleted_abacus_contract_term_accounts') @patch('royalty_collection_territory_backfill.processor.logger.info') def test__cleanup_invalid_territories_no_rows_affected( mock_logger, mock_get_deleted_accounts, mock_get_invalid_territories ): """Test _cleanup_invalid_territories method when no rows are affected.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.rowcount = 0 mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor mock_ar_mysql_conn.commit.return_value = True mock_get_deleted_accounts.return_value = [1, 2, 3, 4] mock_get_invalid_territories.return_value = [] territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._cleanup_invalid_territories() assert result is None mock_get_deleted_accounts.assert_called_once() mock_get_invalid_territories.assert_called_once() assert mock_cursor.execute.call_count == 0 mock_ar_mysql_conn.commit.assert_not_called() mock_logger.assert_has_calls([ call('No territories needed cleanup.') ]) def test__get_invalid_territories_accounts_from_art_relation(): """Test _get_invalid_territories_accounts_from_art_relation method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.fetchall.return_value = [ {'vendor_id': '1'}, {'vendor_id': '2'} ] mock_account_ids = ['1', '2', '3', '4'] mock_ar_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._get_invalid_territories_accounts_from_art_relation( mock_account_ids ) assert result == ['1', '2'] mock_cursor.execute.assert_called_once() def test_get_deleted_abacus_contract_term_accounts(): """Test _get_deleted_abacus_contract_term_accounts method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.fetchall.return_value = [ {'account_id': '1'}, {'account_id': '2'} ] mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._get_deleted_abacus_contract_term_accounts() assert result == ['1', '2'] mock_cursor.execute.assert_called_once() def test_get_no_deleted_abacus_contract_term_accounts(): """Test _get_deleted_abacus_contract_term_accounts method when no term deleted for an account.""" # noqa: E501 mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_cursor.fetchall.return_value = [] mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) result = territoryBackfill._get_deleted_abacus_contract_term_accounts() assert result == [] mock_cursor.execute.assert_called_once() @patch('royalty_collection_territory_backfill.processor.logger.info') def test_process(mock_logger): """Test process method.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) TerritoryBackfillProcessor._get_and_format_countries_from_ar_db = \ MagicMock(return_value=True) TerritoryBackfillProcessor._get_abacus_accounts = \ MagicMock(return_value=['1', '2', '3', '4', '5', '6']) TerritoryBackfillProcessor._cleanup_invalid_territories = \ MagicMock(return_value=['5', '6']) TerritoryBackfillProcessor._batch_account_ids = \ MagicMock(return_value=[['1', '2'], ['3', '4']]) TerritoryBackfillProcessor._create_temp_table_in_art_relations = \ MagicMock(return_value=True) TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories = MagicMock() TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories \ .side_effect = [ [ {'account_id': '1', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '1', 'country_codes': 'USA,CAN,AUS'} ], [ {'account_id': '3', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '4', 'country_codes': 'USA,CAN,AUS'} ] ] TerritoryBackfillProcessor._format_account_and_territories_data = MagicMock() TerritoryBackfillProcessor._format_account_and_territories_data.side_effect = [ [('1', '1,2,3'), ('2', '1,2,3')], [('3', '1,2,3'), ('4', '1,2,3')] ] TerritoryBackfillProcessor._insert_into_temp_table = \ MagicMock(return_value=True) TerritoryBackfillProcessor._update_vendor_contract_and_history_table = \ MagicMock(return_value=['1', '2', '3', '4']) TerritoryBackfillProcessor._save_backfilled_account_list = \ MagicMock(return_value=True) TerritoryBackfillProcessor._notify_success_message = \ MagicMock(return_value=True) TerritoryBackfillProcessor._send_file_to_slack = \ MagicMock(return_value=True) territoryBackfill.process() TerritoryBackfillProcessor._get_and_format_countries_from_ar_db \ .assert_called_once() TerritoryBackfillProcessor._get_abacus_accounts.assert_called_once() TerritoryBackfillProcessor._cleanup_invalid_territories.assert_called_once() TerritoryBackfillProcessor._batch_account_ids \ .assert_called_once_with(['1', '2', '3', '4', '5', '6']) TerritoryBackfillProcessor._create_temp_table_in_art_relations.assert_called_once() TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories \ .assert_has_calls([ call(['1', '2']), call(['3', '4']) ]) TerritoryBackfillProcessor._format_account_and_territories_data \ .assert_has_calls([ call([ {'account_id': '1', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '1', 'country_codes': 'USA,CAN,AUS'} ]), call([ {'account_id': '3', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '4', 'country_codes': 'USA,CAN,AUS'} ]) ]) TerritoryBackfillProcessor._insert_into_temp_table.assert_has_calls([ call([('1', '1,2,3'), ('2', '1,2,3')]), call([('3', '1,2,3'), ('4', '1,2,3')]) ]) TerritoryBackfillProcessor._update_vendor_contract_and_history_table \ .assert_called_once() TerritoryBackfillProcessor._notify_success_message \ .assert_called_once_with(['1', '2', '3', '4']) TerritoryBackfillProcessor._send_file_to_slack.assert_not_called() mock_logger.assert_has_calls([ call('Processing accounts in batches.'), call('Processing account batch 1.'), call('Processing account batch 2.') ]) @patch('royalty_collection_territory_backfill.processor.logger.info') def test_process_qa_env(mock_logger): """Test process method when env is qa.""" mock_cursor = MagicMock() mock_ar_mysql_conn = MagicMock() mock_abacus_mysql_conn = MagicMock() mock_abacus_mysql_conn.cursor.return_value.__enter__.return_value = \ mock_cursor territoryBackfill = TerritoryBackfillProcessor( mock_ar_mysql_conn, mock_abacus_mysql_conn ) TerritoryBackfillProcessor._get_and_format_countries_from_ar_db = \ MagicMock(return_value=True) TerritoryBackfillProcessor._get_abacus_accounts = \ MagicMock(return_value=['1', '2', '3', '4']) TerritoryBackfillProcessor._cleanup_invalid_territories = \ MagicMock(return_value=['5', '6']) TerritoryBackfillProcessor._batch_account_ids = \ MagicMock(return_value=[['1', '2'], ['3', '4']]) TerritoryBackfillProcessor._create_temp_table_in_art_relations = \ MagicMock(return_value=True) TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories = MagicMock() TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories \ .side_effect = [ [ {'account_id': '1', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '1', 'country_codes': 'USA,CAN,AUS'} ], [ {'account_id': '3', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '4', 'country_codes': 'USA,CAN,AUS'} ] ] TerritoryBackfillProcessor._format_account_and_territories_data = MagicMock() TerritoryBackfillProcessor._format_account_and_territories_data.side_effect = [ [('1', '1,2,3'), ('2', '1,2,3')], [('3', '1,2,3'), ('4', '1,2,3')] ] TerritoryBackfillProcessor._insert_into_temp_table = \ MagicMock(return_value=True) TerritoryBackfillProcessor._update_vendor_contract_and_history_table = \ MagicMock(return_value=['1', '2', '3', '4']) TerritoryBackfillProcessor._save_backfilled_account_list = \ MagicMock(return_value=True) TerritoryBackfillProcessor._notify_success_message = \ MagicMock(return_value=True) TerritoryBackfillProcessor._send_file_to_slack = \ MagicMock(return_value=True) with patch.multiple( 'royalty_collection_territory_backfill.processor', ENVIRONMENT='qa', CHANNEL_ID='1234' ): territoryBackfill.process() TerritoryBackfillProcessor._get_and_format_countries_from_ar_db \ .assert_called_once() TerritoryBackfillProcessor._get_abacus_accounts.assert_called_once() TerritoryBackfillProcessor._cleanup_invalid_territories.assert_called_once() TerritoryBackfillProcessor._batch_account_ids \ .assert_called_once_with(['1', '2', '3', '4']) TerritoryBackfillProcessor._create_temp_table_in_art_relations.assert_called_once() TerritoryBackfillProcessor._get_abacus_accounts_and_their_territories \ .assert_has_calls([ call(['1', '2']), call(['3', '4']) ]) TerritoryBackfillProcessor._format_account_and_territories_data \ .assert_has_calls([ call([ {'account_id': '1', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '1', 'country_codes': 'USA,CAN,AUS'} ]), call([ {'account_id': '3', 'country_codes': 'USA,CAN,AUS'}, {'account_id': '4', 'country_codes': 'USA,CAN,AUS'} ]) ]) TerritoryBackfillProcessor._insert_into_temp_table.assert_has_calls([ call([('1', '1,2,3'), ('2', '1,2,3')]), call([('3', '1,2,3'), ('4', '1,2,3')]) ]) TerritoryBackfillProcessor._update_vendor_contract_and_history_table \ .assert_called_once() TerritoryBackfillProcessor._notify_success_message \ .assert_called_once_with(['1', '2', '3', '4']) TerritoryBackfillProcessor._send_file_to_slack \ .assert_called_once_with(['1', '2', '3', '4']) mock_logger.assert_has_calls([ call('Processing accounts in batches.'), call('Processing account batch 1.'), call('Processing account batch 2.') ])