"""Integration tests for contract reserves endpoints.""" import pytest import requests from abacus_contract.tests.integration import conftest from abacus_contract.tests.integration.consts import api, constants from abacus_contract.tests.integration.utils import generic_helper _RESERVE_BODY = { 'installments_in_months': 2, 'reserve_rate': 1.8, 'reserve_release_offset_in_months': 1, } @pytest.mark.jira('ACC-4555') def test_post_get_contract_reserves( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """Check reserves endpoints.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) # defined in fixtures in conftest.py contract_id = 1 post_reserves_body = { 'installments_in_months': 2, 'reserve_rate': 1.8, 'reserve_release_offset_in_months': 1, } res_post = ows_abacus_contract_client.post_contract_reserves( contract_id, post_reserves_body ) assert res_post.status_code == 201 res_get = ows_abacus_contract_client.get_contract_reserves(contract_id) assert res_get.status_code == 200 res_get_body = res_get.json() assert ( res_get_body['installments_in_months'] == post_reserves_body['installments_in_months'] ) assert float(res_get_body['reserve_rate']) == post_reserves_body['reserve_rate'] assert ( res_get_body['reserve_release_offset_in_months'] == post_reserves_body['reserve_release_offset_in_months'] ) assert res_get_body['contract_id'] == contract_id assert 'release_schedule' in res_get_body contract_reserve_id = res_get_body['contract_reserve_id'] res_get = ows_abacus_contract_client.get_contract_reserves_batch( [contract_reserve_id] ) assert res_get.status_code == 200 res_get_body = res_get.json()[0] assert ( res_get_body['installments_in_months'] == post_reserves_body['installments_in_months'] ) assert float(res_get_body['reserve_rate']) == post_reserves_body['reserve_rate'] assert ( res_get_body['reserve_release_offset_in_months'] == post_reserves_body['reserve_release_offset_in_months'] ) assert res_get_body['contract_id'] == contract_id assert 'release_schedule' in res_get_body res_get = ows_abacus_contract_client.get_contract_reserves_by_contract_ids( [contract_id] ) assert res_get.status_code == 200 res_get_body = res_get.json()[0] assert ( res_get_body['installments_in_months'] == post_reserves_body['installments_in_months'] ) assert float(res_get_body['reserve_rate']) == post_reserves_body['reserve_rate'] assert ( res_get_body['reserve_release_offset_in_months'] == post_reserves_body['reserve_release_offset_in_months'] ) assert res_get_body['contract_id'] == contract_id assert 'release_schedule' in res_get_body @pytest.mark.jira('PLATFORM-4470') def test_get_contract_reserves_authorization( admin_headers: dict[str, str], auth_headers: dict[str, str], unauthorized_headers: dict[str, str], ) -> None: """Test authorization for get contract reserves endpoint.""" contract_id, _, _ = generic_helper.create_account_and_contract( account_id=constants.TEST_ACCOUNT_ID ) reserve_dict = { 'installments_in_months': 2, 'reserve_rate': 1.8, 'reserve_release_offset_in_months': 1, } res = requests.post( f'{api.QA_BASE_URL}/contract/{contract_id}/reserves/', headers=admin_headers, json=reserve_dict, ) assert res.status_code == 201 res = requests.get( f'{api.QA_BASE_URL}/contract/{contract_id}/reserves/', headers=auth_headers ) assert res.status_code == 200 assert ( res.json()['installments_in_months'] == reserve_dict['installments_in_months'] ) assert float(res.json()['reserve_rate']) == reserve_dict['reserve_rate'] assert ( res.json()['reserve_release_offset_in_months'] == reserve_dict['reserve_release_offset_in_months'] ) res = requests.get( f'{api.QA_BASE_URL}/contract/{contract_id}/reserves/', headers=unauthorized_headers, ) assert res.status_code == 403 assert res.json()['message'] == 'User is forbidden' @pytest.mark.jira('ACC-5363') def test_put_contract_reserves( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """Check PUT /contract_reserve endpoint.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) # defined in fixtures in conftest.py contract_id = 1 post_reserves_body = { 'installments_in_months': 2, 'reserve_rate': 1.8, 'reserve_release_offset_in_months': 1, } res_post = ows_abacus_contract_client.post_contract_reserves( contract_id, post_reserves_body ) assert res_post.status_code == 201 put_reserves_body = { 'installments_in_months': 6, 'reserve_rate': 2.40, 'reserve_release_offset_in_months': 3, } res_put = ows_abacus_contract_client.put_contract_reserves( contract_id, put_reserves_body ) assert res_put.status_code == 201 assert float(res_put.json()['reserve_rate']) == put_reserves_body['reserve_rate'] assert ( res_put.json()['installments_in_months'] == put_reserves_body['installments_in_months'] ) assert ( res_put.json()['reserve_release_offset_in_months'] == put_reserves_body['reserve_release_offset_in_months'] ) res_get = ows_abacus_contract_client.get_contract_reserves_by_contract_ids( [contract_id] ) assert res_get.status_code == 200 assert float(res_get.json()[0]['reserve_rate']) == put_reserves_body['reserve_rate'] assert ( res_get.json()[0]['installments_in_months'] == put_reserves_body['installments_in_months'] ) assert ( res_get.json()[0]['reserve_release_offset_in_months'] == put_reserves_body['reserve_release_offset_in_months'] ) @pytest.mark.jira('ACC-10151') def test_delete_contract_reserve( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """DELETE /contract//reserves/ soft-deletes the active reserve.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) # Contract id is seeded by create_contract_fixture contract_id = 1 # Seed a reserve res_post = ows_abacus_contract_client.post_contract_reserves( contract_id, _RESERVE_BODY ) assert res_post.status_code == 201 # Verify it exists and the body matches what was posted res_get = ows_abacus_contract_client.get_contract_reserves(contract_id) assert res_get.status_code == 200 res_get_body = res_get.json() assert ( res_get_body['installments_in_months'] == _RESERVE_BODY['installments_in_months'] ) assert float(res_get_body['reserve_rate']) == _RESERVE_BODY['reserve_rate'] assert ( res_get_body['reserve_release_offset_in_months'] == _RESERVE_BODY['reserve_release_offset_in_months'] ) # Delete the reserve res_delete = ows_abacus_contract_client.delete_contract_reserves(contract_id) assert res_delete.status_code == 204 # After soft-deletion the GET endpoint still returns 200 but with an empty body res_get_after = ows_abacus_contract_client.get_contract_reserves(contract_id) assert res_get_after.status_code == 200 assert res_get_after.json() == {} # Batch lookup by contract_id should also exclude the deleted reserve res_batch = ows_abacus_contract_client.get_contract_reserves_by_contract_ids( [contract_id] ) assert res_batch.status_code == 200 assert res_batch.json() == [] @pytest.mark.jira('ACC-10151') def test_delete_contract_reserve_no_active_reserve( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """DELETE /contract//reserves/ returns 400 when no active reserve exists.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) # Contract id is seeded by create_contract_fixture; no reserve is posted contract_id = 1 res_delete = ows_abacus_contract_client.delete_contract_reserves(contract_id) assert res_delete.status_code == 400 @pytest.mark.jira('ACC-10151') def test_delete_contract_reserve_contract_not_found( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """DELETE /contract//reserves/ returns 400 for a non-existent contract.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) non_existent_contract_id = 999999 res_delete = ows_abacus_contract_client.delete_contract_reserves( non_existent_contract_id ) assert res_delete.status_code == 400 @pytest.mark.jira('ACC-10151') def test_delete_contract_reserve_idempotency( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """DELETE /contract//reserves/ returns 400 on a second delete attempt.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) contract_id = 1 # Seed and delete a reserve res_post = ows_abacus_contract_client.post_contract_reserves( contract_id, _RESERVE_BODY ) assert res_post.status_code == 201 res_first_delete = ows_abacus_contract_client.delete_contract_reserves(contract_id) assert res_first_delete.status_code == 204 # Second delete attempt: no active reserve remains res_second_delete = ows_abacus_contract_client.delete_contract_reserves(contract_id) assert res_second_delete.status_code == 400 @pytest.mark.jira('ACC-10151') def test_delete_then_recreate_contract_reserve( basic_headers, create_account_fixture, create_contract_fixture, create_account_contract_fixture, create_account_tax_info_fixture, ): """A new reserve can be POSTed after the previous one is soft-deleted.""" ows_abacus_contract_client = conftest.ows_abacus_contract_api_client(basic_headers) contract_id = 1 res_post = ows_abacus_contract_client.post_contract_reserves( contract_id, _RESERVE_BODY ) assert res_post.status_code == 201 res_delete = ows_abacus_contract_client.delete_contract_reserves(contract_id) assert res_delete.status_code == 204 new_reserve_body = { 'installments_in_months': 6, 'reserve_rate': 3.5, 'reserve_release_offset_in_months': 2, } res_post_new = ows_abacus_contract_client.post_contract_reserves( contract_id, new_reserve_body ) assert res_post_new.status_code == 201 res_get = ows_abacus_contract_client.get_contract_reserves(contract_id) assert res_get.status_code == 200 res_get_body = res_get.json() assert float(res_get_body['reserve_rate']) == new_reserve_body['reserve_rate'] assert ( res_get_body['installments_in_months'] == new_reserve_body['installments_in_months'] ) assert ( res_get_body['reserve_release_offset_in_months'] == new_reserve_body['reserve_release_offset_in_months'] )