"""Unit Tests for contract_term_schedule logic.""" from unittest.mock import MagicMock, patch from abacus_contract.logic import contract_term_schedule as logic from abacus_contract.tests.utils.factories import ( ContractTermFactory, ContractTermScheduleFactory, ) @patch('abacus_contract.logic.contract_term_schedule.models') def test_get_contract_term_schedules_by_term_id(mock_models, create_mock_schedule): """Test get_contract_term_schedules_by_term_id function.""" mock_contract_term = ContractTermFactory.create() mock_contract_term_schedule = ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=2 ) mock_models.ContractTerm.get_by_id_or_error.return_value = mock_contract_term mock_models.ContractTermSchedule.get_by_term_id.return_value = [ mock_contract_term_schedule ] contract_term_id = mock_contract_term.contract_term_id res = logic.get_contract_term_schedules_by_term_id(contract_term_id) assert res.status == 200 assert res.message == [ { 'contract_term_schedule_id': mock_contract_term_schedule.contract_term_schedule_id, 'contract_term_id': contract_term_id, 'schedule_id': mock_contract_term_schedule.schedule_id, } ] mock_models.ContractTermSchedule.get_by_term_id.assert_called_once_with( contract_term_id ) @patch('abacus_contract.logic.contract_term_schedule.models') def test_get_contract_term_schedule_records_by_term_ids( mock_models, create_mock_schedule ): """Records are flat and each carries its contract_term_id.""" mock_contract_term = ContractTermFactory.create() contract_term_id = mock_contract_term.contract_term_id schedule_1 = ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=1 ) schedule_2 = ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=2 ) mock_models.ContractTermSchedule.get_by_term_ids.return_value = [ schedule_1, schedule_2, ] res = logic.get_contract_term_schedule_records_by_term_ids([contract_term_id]) mock_models.ContractTermSchedule.get_by_term_ids.assert_called_once_with( [contract_term_id] ) # A flat list of records, not the {'data': ...} dataload wrapping. assert len(res) == 2 assert all(record['contract_term_id'] == contract_term_id for record in res) @patch('abacus_contract.logic.contract_term_schedule.models') def test_get_contract_term_schedule_records_by_term_ids_empty_skips_query(mock_models): """No authorized ids: returns an empty list without querying. The dataloader helper only ever passes the authorized ids through, so an id that never resolved to an account, or whose account wasn't authorized, must never reach this function's query. """ res = logic.get_contract_term_schedule_records_by_term_ids([]) assert res == [] mock_models.ContractTermSchedule.get_by_term_ids.assert_not_called() @patch('abacus_contract.logic.contract_term_schedule.models') def test_create_contract_term_schedules(mock_models, create_mock_schedule): """Test create_contract_term_schedules function.""" mock_contract_term = ContractTermFactory.create() schedule_ids = ['1'] mock_contract_term_schedule = ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=schedule_ids[0] ) mock_models.ContractTermSchedule.build.return_value = mock_contract_term_schedule mock_models.ContractTermSchedule.commit_changes.return_value = True params = { 'schedule_ids': schedule_ids, 'contract_term_id': mock_contract_term.contract_term_id, } result = logic.create_contract_term_schedules(**params) assert result == [mock_contract_term_schedule] assert mock_models.ContractTermSchedule.build.call_count == len(schedule_ids) mock_models.ContractTermSchedule.build.assert_called_once_with( contract_term_id=mock_contract_term.contract_term_id, schedule_id=schedule_ids[0], ) mock_models.ContractTermSchedule.commit_changes.assert_called_once() @patch('abacus_contract.logic.contract_term_schedule.models') def test_delete_contract_term_schedules(mock_models, create_mock_schedule): """Test delete_or_restore_contract_term_schedules function. Existing term schedules will be deleted if related schedule_ids are not included in the PUT request. """ mock_contract_term = ContractTermFactory.create() schedule_ids = [1, 3] mock_contract_term_schedules = dict( [ ( schedule_id, ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=schedule_id ), ) for schedule_id in schedule_ids ] ) mock_contract_term_schedules[1].delete_by_id_or_error = MagicMock() params = { 'existing_schedules': mock_contract_term_schedules, 'existing_term_schedule_ids': schedule_ids, 'new_schedule_ids': [3], } result = logic.delete_or_restore_contract_term_schedules(**params) assert not result mock_contract_term_schedules[1].delete_by_id_or_error.assert_called_once_with( mock_contract_term_schedules[1].contract_term_schedule_id, soft_delete=True ) @patch('abacus_contract.logic.contract_term_schedule.models') def test_restore_contract_term_schedules(mock_models, create_mock_schedule): """Test delete_or_restore_contract_term_schedules function. Term schedules will be added back if they are deleted previously but included in the PUT request. """ mock_contract_term = ContractTermFactory.create() schedule_ids = [1, 3] mock_contract_term_schedules = [ ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=schedule_id, deleted_by=None if schedule_id == 1 else 'test_user', deleted_at=None if schedule_id == 1 else '2023-08-21', ) for schedule_id in schedule_ids ] existing_contract_term_schedules = { schedule_ids[0]: mock_contract_term_schedules[0], schedule_ids[1]: mock_contract_term_schedules[1], } mock_contract_term_schedules[1].update_attributes = MagicMock() mock_models.ContractTermSchedule.commit_changes.return_value = True params = { 'existing_schedules': existing_contract_term_schedules, 'existing_term_schedule_ids': schedule_ids, 'new_schedule_ids': [1, 3], } result = logic.delete_or_restore_contract_term_schedules(**params) existing_contract_term_schedules[1].deleted_at = None existing_contract_term_schedules[1].deleted_by = None assert result == [mock_contract_term_schedules[1]] mock_contract_term_schedules[1].update_attributes.assert_called_once_with( contract_term_schedule_id=mock_contract_term_schedules[ 1 ].contract_term_schedule_id, deleted_by=None, deleted_at=None, ) mock_models.ContractTermSchedule.commit_changes.assert_called_once() @patch('abacus_contract.logic.contract_term_schedule.create_contract_term_schedules') @patch('abacus_contract.logic.contract_term_schedule.models') def test_create_or_update_contract_term_schedules( mock_models, mock_create_contract_term_schedules ): """Test create_or_update_contract_term_schedules function for new schedule_ids.""" mock_contract_term = ContractTermFactory.create() schedule_ids = ['1', '2'] contract_term_id = mock_contract_term.contract_term_id mock_models.ContractTerm.get_by_id.return_value = mock_contract_term mock_create_contract_term_schedules.return_value = [] params = {'schedule_ids': schedule_ids, 'contract_term_id': contract_term_id} result = logic.create_or_update_contract_term_schedules(**params) assert result.status == 200 mock_create_contract_term_schedules.assert_called_once_with( schedule_ids, contract_term_id ) @patch( 'abacus_contract.logic.contract_term_schedule' '.delete_or_restore_contract_term_schedules' ) @patch('abacus_contract.logic.contract_term_schedule.models') def test_create_or_update_contract_term_schedules_existing_schedule_ids( mock_models, mock_delete_or_restore_contract_term_schedules, create_mock_schedule ): """Test create_or_update_contract_term_schedules function for existing schedule_ids.""" mock_contract_term = ContractTermFactory.create() schedule_ids = ['1', '2'] contract_term_id = mock_contract_term.contract_term_id mock_contract_term_schedules = [ ContractTermScheduleFactory.create( contract_term=mock_contract_term, schedule_id=schedule_id, ) for schedule_id in schedule_ids ] mock_models.ContractTerm.get_by_id.return_value = mock_contract_term mock_delete_or_restore_contract_term_schedules.return_value = None params = {'schedule_ids': ['1'], 'contract_term_id': contract_term_id} existing_contract_term_schedules = { schedule_ids[0]: mock_contract_term_schedules[0], schedule_ids[1]: mock_contract_term_schedules[1], } result = logic.create_or_update_contract_term_schedules(**params) assert result.status == 200 mock_delete_or_restore_contract_term_schedules.assert_called_once_with( existing_contract_term_schedules, schedule_ids, ['1'] )