"""Unit tests for contract_lifecycle_schedule endpoints.""" from unittest.mock import MagicMock, patch from flask import testing from owsresponse import response import pytest from abacus_contract.schemas.contract_lifecycle_schedule import \ ContractLifecycleScheduleSchema from tests.utils.factories import ContractFactory from tests.utils.factories import ContractLifecycleScheduleFactory @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_get_contract_lifecycle_schedules_by_contract_id(mock_logic, fixture_client): """Test GET contract lifecycle schedules by contract_id.""" mock_contract_lifecycle_schedules = [ContractLifecycleScheduleFactory.create()] contract_id = mock_contract_lifecycle_schedules[0].contract_id mock_logic.get_contract_lifecycle_schedules_by_contract_id.return_value =\ response.Response( message=ContractLifecycleScheduleSchema(many=True).dump( mock_contract_lifecycle_schedules ), status=200 ) res = fixture_client.get( f'/contract/{contract_id}/contract-lifecycle-schedules/' ) assert res.status_code == 200 mock_logic.get_contract_lifecycle_schedules_by_contract_id.assert_called_once_with( contract_id ) @pytest.mark.parametrize( [ 'standalone_check_result', 'get_account_id_result', 'pdp_auth_result', 'expected_status', ], [ pytest.param(True, None, None, 200, id='Standalone check pass'), pytest.param(False, None, None, 404, id='Account not found'), pytest.param(False, 9, False, 403, id='PDP auth fail'), pytest.param(False, 9, True, 200, id='PDP auth pass'), ], ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.pdp_authorize_many_accounts') # noqa: E501 @patch('abacus_contract.blueprints.contract_lifecycle_schedule.contract_logic') @patch('abacus_contract.blueprints.contract_lifecycle_schedule.flask_request') def tests_get_contract_lifecycle_schedules_by_contract_id_authorization( mock_flask_request: MagicMock, mock_contract_logic: MagicMock, mock_authorization: MagicMock, standalone_check_result: bool, get_account_id_result: int | None, pdp_auth_result: bool | None, expected_status: int, fixture_client ): """Test authorization for getting contract lifecycle schedules by contract id.""" mock_flask_request.verify_rules_access_standalone.return_value = \ standalone_check_result mock_contract_logic.get_account_id_by_contract_id.return_value = \ get_account_id_result mock_authorization.return_value = \ pdp_auth_result contract_id = 1 res = fixture_client.get(f'/contract/{contract_id}/contract-lifecycle-schedules/') assert res.status_code == expected_status mock_flask_request.verify_rules_access_standalone.assert_called_once() if not standalone_check_result: mock_contract_logic.get_account_id_by_contract_id.assert_called_once_with( contract_id ) if get_account_id_result: mock_authorization.assert_called_once_with( [get_account_id_result] ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_get_contract_lifecycle_schedules_by_ids( mock_logic: MagicMock, fixture_client: testing.FlaskClient ) -> None: """Test GET contract lifecycle schedules by ids.""" mock_contract_lifecycle_schedules = [ContractLifecycleScheduleFactory.create()] ids = [ mock_contract_lifecycle_schedules[0].contract_lifecycle_schedule_id ] mock_logic.get_contract_lifecycle_schedules_by_ids.return_value =\ response.Response( message=ContractLifecycleScheduleSchema(many=True).dump( mock_contract_lifecycle_schedules ), status=200 ) res = fixture_client.post( '/contract-lifecycle-schedules/dataloader', json=ids ) assert res.status_code == 200 mock_logic.get_contract_lifecycle_schedules_by_ids.assert_called_once_with( ids ) @pytest.mark.parametrize( [ 'standalone_check_result', 'get_account_ids_result', 'pdp_auth_result', 'expected_status', ], [ pytest.param(True, None, None, 200, id='Standalone check pass'), pytest.param(False, [], None, 403, id='Account not found'), pytest.param(False, [9], False, 403, id='PDP auth fail'), pytest.param(False, [9], True, 200, id='PDP auth pass'), ], ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.pdp_authorize_many_accounts') # noqa: E501 @patch('abacus_contract.blueprints.contract_lifecycle_schedule.contract_logic') @patch('abacus_contract.blueprints.contract_lifecycle_schedule.flask_request') @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_get_contract_lifecycle_schedules_dataloader_authorization( mock_logic: MagicMock, mock_flask_request: MagicMock, mock_contract_logic: MagicMock, mock_authorization: MagicMock, standalone_check_result: bool, get_account_ids_result: list[int] | None, pdp_auth_result: bool | None, expected_status: int, fixture_client ): """Test authorization for getting contract lifecycle schedules dataloader.""" mock_flask_request.verify_rules_access_standalone.return_value = \ standalone_check_result mock_contract_logic.get_account_ids_by_contract_ids.return_value = \ get_account_ids_result mock_authorization.return_value = \ pdp_auth_result schedule = ContractLifecycleScheduleFactory.create() mock_contract_lifecycle_schedules = [schedule] ids = [ mock_contract_lifecycle_schedules[0].contract_lifecycle_schedule_id ] mock_logic.get_contract_lifecycle_schedules_by_ids.return_value =\ response.Response( message=[{'data': ContractLifecycleScheduleSchema().dump(schedule)}], status=200 ) res = fixture_client.post('/contract-lifecycle-schedules/dataloader', json=ids) assert res.status_code == expected_status mock_flask_request.verify_rules_access_standalone.assert_called_once() if not standalone_check_result: mock_contract_logic.get_account_ids_by_contract_ids.assert_called_once_with( [schedule.contract_id] ) mock_authorization.assert_called_once_with(get_account_ids_result) else: mock_contract_logic.get_account_ids_by_contract_ids.assert_not_called() mock_authorization.assert_not_called() @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_create_contract_lifecycle_schedules(mock_logic, fixture_client): """Test creating contract_lifecycle_schedules.""" mock_contract = ContractFactory.create() mock_logic.create_contract_lifecycle_schedules.return_value =\ response.Response( message='OK', status=201 ) mock_post_request_body = [{ 'renewal_type': 'continuously_active', 'termination_notice_detail_interval': 90, 'termination_notice_detail_type': 'day' }] res = fixture_client.post( f'/contract/{mock_contract.contract_id}/contract-lifecycle-schedules/', json=mock_post_request_body ) assert res.status_code == 201 mock_logic.create_contract_lifecycle_schedules.assert_called_once_with( mock_contract.contract_id, mock_post_request_body, allow_end_date_in_past=False ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_create_contract_lifecycle_schedules_allow_end_date_in_past( mock_logic, fixture_client ): """Test creating contract_lifecycle_schedules when allow_end_date_in_past True.""" mock_contract = ContractFactory.create() mock_logic.create_contract_lifecycle_schedules.return_value =\ response.Response( message='OK', status=201 ) mock_post_request_body = [{ 'renewal_type': 'continuously_active', 'termination_notice_detail_interval': 90, 'termination_notice_detail_type': 'day' }] res = fixture_client.post( f'/contract/{mock_contract.contract_id}/contract-lifecycle-schedules' f'?allow_end_date_in_past=true', json=mock_post_request_body ) assert res.status_code == 201 mock_logic.create_contract_lifecycle_schedules.assert_called_once_with( mock_contract.contract_id, mock_post_request_body, allow_end_date_in_past=True ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_update_contract_lifecycle_schedules(mock_logic, fixture_client): """Test updating contract_lifecycle_schedules.""" mock_contract = ContractFactory.create() mock_logic.update_contract_lifecycle_schedules.return_value =\ response.Response( message='OK', status=200 ) mock_put_request_body = [{ 'contract_lifecycle_schedule_id': 1, 'renewal_type': 'continuously_active', 'termination_notice_detail_interval': 90, 'termination_notice_detail_type': 'day' }] res = fixture_client.put( f'/contract/{mock_contract.contract_id}/contract-lifecycle-schedules/', json=mock_put_request_body ) assert res.status_code == 200 mock_logic.update_contract_lifecycle_schedules.assert_called_once_with( mock_contract.contract_id, mock_put_request_body, allow_end_date_in_past=False ) @patch('abacus_contract.blueprints.contract_lifecycle_schedule.logic') def test_update_contract_lifecycle_schedules_allo_end_date_in_past( mock_logic, fixture_client ): """Test updating contract_lifecycle_schedules when allow_end_date_in_past True.""" mock_contract = ContractFactory.create() mock_logic.update_contract_lifecycle_schedules.return_value =\ response.Response( message='OK', status=200 ) mock_put_request_body = [{ 'contract_lifecycle_schedule_id': 1, 'renewal_type': 'continuously_active', 'termination_notice_detail_interval': 90, 'termination_notice_detail_type': 'day' }] res = fixture_client.put( f'/contract/{mock_contract.contract_id}/contract-lifecycle-schedules' f'?allow_end_date_in_past=true', json=mock_put_request_body ) assert res.status_code == 200 mock_logic.update_contract_lifecycle_schedules.assert_called_once_with( mock_contract.contract_id, mock_put_request_body, allow_end_date_in_past=True )