"""Test ows-abacus-account requests.""" from typing import Any import urllib.parse from faker import Faker import httpx from owsclient.test import OwsClientMock import pytest from src.connectors.ows_account import ( account_payment_term_dataloader, get_account_payment_hold, get_accounts, get_eligible_accounts, ) from src.exceptions import OwsAccountException from src.models import Account, AccountPaymentHold, GetAccountsResponse from tests.unit.factories import ( AccountFactory, AccountPaymentHoldFactory, AccountPaymentTermDataloaderItemFactory, GetAccountsResponseFactory, ) def test_get_eligible_accounts_success(ows_client_mock: OwsClientMock) -> None: """Test successfully getting eligible accounts.""" eligible_accounts = [AccountFactory.build(), AccountFactory.build()] payment_group_id = 33 ows_client_mock.get( 'ows-abacus-account', f'/payment-group/{payment_group_id}/eligible-accounts' ).mock( return_value=httpx.Response( status_code=200, json=[Account.model_dump(a, mode='json') for a in eligible_accounts], ) ) res = get_eligible_accounts(payment_group_id) assert res == eligible_accounts def test_get_eligible_accounts_failure(ows_client_mock: OwsClientMock) -> None: """Test failure getting eligible accounts.""" payment_group_id = 333 ows_client_mock.get( 'ows-abacus-account', f'/payment-group/{payment_group_id}/eligible-accounts' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsAccountException, match='ERROR in GET /payment-group/333/eligible-accounts' ): get_eligible_accounts(payment_group_id) @pytest.mark.parametrize('agreement_type_ids', [None, [1, 2]]) def test_get_accounts_success( ows_client_mock: OwsClientMock, agreement_type_ids: int | None ) -> None: """Test successfully calling get_accounts.""" accounts_response = GetAccountsResponseFactory.build() params: dict[str, Any] = { 'limit': 100, 'offset': 200, 'reference_payment_type_id': 1, } if agreement_type_ids: params['agreement_type_ids'] = agreement_type_ids query_string = urllib.parse.urlencode(params, doseq=True) ows_client_mock.get('ows-abacus-account', f'/accounts/?{query_string}').mock( return_value=httpx.Response( status_code=200, json=GetAccountsResponse.model_dump(accounts_response, mode='json'), ) ) res = get_accounts(**params) assert res == accounts_response def test_get_accounts_failure(ows_client_mock: OwsClientMock) -> None: """Test failure calling get_accounts.""" params: dict[str, Any] = { 'limit': 100, 'offset': 200, 'reference_payment_type_id': 1, } query_string = urllib.parse.urlencode(params) ows_client_mock.get('ows-abacus-account', f'/accounts/?{query_string}').mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises( OwsAccountException, match=f'ERROR in GET /accounts/\?{query_string}' ): get_accounts(**params) def test_get_account_payment_hold_success(ows_client_mock: OwsClientMock) -> None: """Test successfully getting account payment hold.""" payment_hold = AccountPaymentHoldFactory.build() ows_client_mock.get( 'ows-abacus-account', f'/account/{payment_hold.account_id}/payment-hold' ).mock( return_value=httpx.Response( status_code=200, json=AccountPaymentHold.model_dump(payment_hold) ) ) res = get_account_payment_hold(payment_hold.account_id) assert res == payment_hold def test_get_account_payment_hold_failure(ows_client_mock: OwsClientMock) -> None: """Test failure getting account payment hold.""" account_id = 123 ows_client_mock.get( 'ows-abacus-account', f'/account/{account_id}/payment-hold' ).mock(return_value=httpx.Response(status_code=400, json='error')) with pytest.raises( OwsAccountException, match=f'ERROR in GET /account/{account_id}/payment-hold' ): get_account_payment_hold(account_id) def test_account_payment_term_dataloader_success( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test account_payment_term dataloader success.""" items = AccountPaymentTermDataloaderItemFactory.batch(faker.pyint(1, 5)) account_ids = faker.pylist(allowed_types=[int]) path_pattern = f'/account/account-payment-term/dataloader' ows_client_mock.post('ows-abacus-account', path_pattern, json=account_ids).mock( return_value=httpx.Response( status_code=200, json=[item.model_dump(mode='json') for item in items], ) ) res = account_payment_term_dataloader(account_ids) assert res == {item.data.account_id: item.data for item in items if item.data} def test_account_payment_term_dataloader_failure( ows_client_mock: OwsClientMock, faker: Faker ) -> None: """Test account_payment_term dataloader failure.""" account_ids = faker.pylist(allowed_types=[int]) path_pattern = f'/account/account-payment-term/dataloader' ows_client_mock.post('ows-abacus-account', path_pattern, json=account_ids).mock( return_value=httpx.Response(status_code=400, json='error') ) with pytest.raises(OwsAccountException, match=f'ERROR in POST {path_pattern}'): account_payment_term_dataloader(account_ids)