"""Unit tests for the adjustments validation logic.""" from unittest.mock import MagicMock, call, patch from abacus_common_logic.adjustments_validation.adjustments_validation import ( _build_full_account_upc_map, _collect_data_to_validate, _fetch_existing_data, _validate_adjustment, validate_adjustments, ) from abacus_common_logic.adjustments_validation.adjustments_validation_data import ( AdjustmentsValidationData, ) from abacus_common_logic.adjustments_validation.utils import clean_upc @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation._collect_data_to_validate' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation._fetch_existing_data' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation._validate_adjustment' ) def test_validate_adjustments( validate_mock, fetch_mock, collect_mock, adjustments_mock ): """Test validating a list of manual adjustments.""" statement_period_id = 1 data_to_validate = AdjustmentsValidationData() existing_data = AdjustmentsValidationData() sf_executor_mock = MagicMock() collect_mock.return_value = data_to_validate fetch_mock.return_value = existing_data validate_mock.side_effect = [[], [], ['ERROR'], ['ERROR']] results = validate_adjustments( adjustments_mock, statement_period_id, sf_executor_mock ) collect_mock.assert_called_once_with(adjustments_mock) fetch_mock.assert_called_once_with( data_to_validate, statement_period_id, sf_executor_mock ) a0, a1, a2, a3 = adjustments_mock validate_mock.assert_any_call(a0, existing_data) validate_mock.assert_any_call(a1, existing_data) validate_mock.assert_any_call(a2, existing_data) validate_mock.assert_any_call(a3, existing_data) assert results == {2: {'ERROR'}, 3: {'ERROR'}} @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.AdjustmentsValidationData' ) def test_collect_data_to_validate(data_class_mock, adjustments_mock): """Test collecting entities to validate.""" data_mock = MagicMock() data_class_mock.return_value = data_mock results = _collect_data_to_validate(adjustments_mock) a0, a1, a2, a3 = adjustments_mock upc = a0['upc'] cleaned_upc = clean_upc(upc) data_mock.add_account_id.assert_any_call(a0['account_id']) data_mock.add_account_id.assert_any_call(a1['account_id']) assert call(a2['account_id']) not in data_mock.add_account_id.mock_calls assert call(a3['account_id']) not in data_mock.add_account_id.mock_calls data_mock.add_account_contract_mapping.assert_any_call( a0['account_id'], a0['contract_id'] ) data_mock.add_account_contract_mapping.assert_any_call( a1['account_id'], a1['contract_id'] ) assert ( call(a2['account_id'], a2['contract_id']) not in data_mock.add_account_contract_mapping.mock_calls ) assert ( call(a3['account_id'], a3['contract_id']) not in data_mock.add_account_contract_mapping.mock_calls ) data_mock.add_upc.assert_any_call(upc) data_mock.add_upc.assert_any_call(cleaned_upc) data_mock.add_account_upc_mapping.assert_any_call(a0['account_id'], upc) data_mock.add_account_upc_mapping.assert_any_call(a0['account_id'], cleaned_upc) data_mock.add_account_contract_upc_mapping.assert_any_call( a0['account_id'], a0['contract_id'], upc ) data_mock.add_account_contract_upc_mapping.assert_any_call( a0['account_id'], a0['contract_id'], cleaned_upc ) data_mock.add_statement_year.assert_any_call(a0['activity_year']) data_mock.add_statement_year.assert_any_call(a1['activity_year']) assert call(a2['activity_year']) not in data_mock.add_statement_year.mock_calls assert call(a3['activity_year']) not in data_mock.add_statement_year.mock_calls data_mock.add_statement_year.assert_any_call(a0['statement_year']) data_mock.add_statement_year.assert_any_call(a1['statement_year']) assert call(a2['statement_year']) not in data_mock.add_statement_year.mock_calls assert call(a3['statement_year']) not in data_mock.add_statement_year.mock_calls assert results == data_mock @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation._build_full_account_upc_map' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.AdjustmentsValidationData' ) def test_fetch_existing_data(data_class_mock, build_map_mock): """Test fetching entities to validate.""" data_to_validate_mock = MagicMock() statement_period_id = 1 existing_data_mock = MagicMock() data_class_mock.return_value = existing_data_mock sf_executor_mock = MagicMock() results = _fetch_existing_data( data_to_validate_mock, statement_period_id, sf_executor_mock ) sf_executor_mock.fetch_close_balance_statuses.assert_called_once_with( statement_period_id ) sf_executor_mock.fetch_accounts.assert_called_once_with( data_to_validate_mock.account_ids ) sf_executor_mock.fetch_account_contracts.assert_called_once_with( data_to_validate_mock.account_contract_map ) sf_executor_mock.fetch_payment_entities.assert_called_once_with( data_to_validate_mock.account_ids ) sf_executor_mock.fetch_display_upcs.assert_called_once_with( data_to_validate_mock.upcs ) sf_executor_mock.fetch_product_terms.assert_called_once_with( data_to_validate_mock.get_contract_ids() ) sf_executor_mock.fetch_label_terms.assert_called_once_with( data_to_validate_mock.get_contract_ids() ) build_map_mock.assert_called_once_with( data_to_validate_mock.account_upc_map, data_to_validate_mock.account_contract_upc_map, data_to_validate_mock.get_contract_account_map(), existing_data_mock.contract_label_map, ) sf_executor_mock.fetch_account_upcs.assert_called_once_with( build_map_mock.return_value ) sf_executor_mock.fetch_statement_periods.assert_called_once_with( data_to_validate_mock.statement_years ) sf_executor_mock.fetch_adjustment_types.assert_called_once() assert results == existing_data_mock def test_build_full_account_upc_map(): """Test building the full map of UPCs by account.""" account_upc_map = {'1': {'111122223333'}} account_contract_upc_map = {'1': {'11': {'111122223333'}, '111': set()}} contract_account_map = {'11': '1', '111': '1'} contract_label_map = {'11': {'1', '2'}, '111': {'1'}, '33': {'3'}} results = _build_full_account_upc_map( account_upc_map, account_contract_upc_map, contract_account_map, contract_label_map, ) assert results == { '1': {'111122223333'}, '2': {'111122223333'}, } @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_flowthrough_payment' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_distribution_type' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_client_facing_comments' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_adjustment_type' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_statement_date' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_activity_date' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_currency' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_amount' ) @patch('abacus_common_logic.adjustments_validation.adjustments_validation.validate_upc') @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_contract' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_account' ) @patch( 'abacus_common_logic.adjustments_validation.adjustments_validation.validate_close_balance_status' ) def test_validate_adjustment( validate_balance_mock, validate_account_mock, validate_contract_mock, validate_upc_mock, validate_amount_mock, validate_currency_mock, validate_activity_date_mock, validate_statement_date_mock, validate_adjustment_type_mock, validate_comments_mock, validate_distribution_type_mock, validate_flowthrough_payment_mock, adjustments_mock, ): """Test validating an adjustment.""" adjustment = adjustments_mock[0] existing_data = MagicMock() validate_balance_mock.return_value = True validate_account_mock.return_value = True validate_contract_mock.return_value = True validate_upc_mock.return_value = True validate_amount_mock.return_value = 'AMOUNT ERROR' validate_currency_mock.return_value = 'CURRENCY ERROR' validate_activity_date_mock.return_value = True validate_statement_date_mock.return_value = True validate_adjustment_type_mock.return_value = True validate_comments_mock.return_value = True validate_distribution_type_mock.return_value = True validate_flowthrough_payment_mock.return_value = 'FLOWTHROUGH ERROR' results = _validate_adjustment(adjustment, existing_data) validate_balance_mock.assert_called_once_with( adjustment['account_id'], existing_data.account_payment_entity_map, existing_data.payment_entity_close_balance_status_map, ) validate_account_mock.assert_called_once_with( adjustment['account_id'], existing_data.account_ids ) validate_contract_mock.assert_called_once_with( adjustment['account_id'], adjustment['contract_id'], existing_data.account_contract_map, ) validate_upc_mock.assert_called_once_with( adjustment['upc'], adjustment['distribution_type'], adjustment['contract_id'], existing_data.contract_product_map, existing_data.contract_label_map, existing_data.display_upc_upc_map, existing_data.account_upc_map, ) validate_amount_mock.assert_called_once_with(adjustment['amount']) validate_currency_mock.assert_called_once_with(adjustment['currency']) validate_activity_date_mock.assert_called_once_with( adjustment['activity_month'], adjustment['activity_year'], existing_data.statement_periods, ) validate_statement_date_mock.assert_called_once_with( adjustment['statement_month'], adjustment['statement_year'], existing_data.statement_periods, ) validate_adjustment_type_mock.assert_called_once_with( adjustment['adjustment_type'], existing_data.adjustment_types ) validate_comments_mock.assert_called_once_with(adjustment['client_facing_comments']) validate_distribution_type_mock.assert_called_once_with( adjustment['distribution_type'], adjustment['upc'] ) validate_flowthrough_payment_mock.assert_called_once_with( adjustment['apply_to_flowthrough_payment'], adjustment['adjustment_type'] ) assert results == ['AMOUNT ERROR', 'CURRENCY ERROR', 'FLOWTHROUGH ERROR']