"""Functional tests for account_tax_info endpoints.""" from unittest.mock import MagicMock, patch from flask.testing import FlaskClient import pytest from abacus_account.constants import error from abacus_account.models.account_tax_info import AccountTaxInfo from tests.utils.factories import AccountFactory from tests.utils.factories import AccountTaxInfoFactory def test_update_account_tax_info(fixture_client, mocker): """Test updating an existing account_tax_info.""" mocker.patch('abacus_account.blueprints.account_tax_info' '.validate_record_owner', return_value=True) mocker.patch('abacus_account.blueprints.account_tax_info' '.permissions_authorize_many_accounts', return_value=True) mocker.patch('abacus_account.logic.account_tax_info.emit_account_tax_id_event', return_value=True) assert AccountTaxInfo.query.count() == 0 account_tax_info = AccountTaxInfoFactory.create( country_of_tax_residence='GBR', is_sba_signed=False, ) assert AccountTaxInfo.query.count() == 1 put_data = { 'is_sba_signed': True, 'is_tax_treaty_claimed': True } response = fixture_client.put( f'/account-tax-info/{account_tax_info.account_tax_info_id}', json=put_data, headers={ 'Content-Type': 'application/json', 'Orchard-Profile-Id': 1234, 'Orchard-Profile-Type': 'DocumentsProfile', } ) assert response.status_code == 201 assert response.json == { 'account_tax_info_id': account_tax_info.account_tax_info_id, 'account_id': account_tax_info.account_id, 'country_of_tax_residence': 'GBR', 'is_sba_signed': True, 'is_vat_exempt': True, 'is_tax_treaty_claimed': True, 'tax_employment_type': None, 'certificate_of_residence_expiration_date': None, 'is_wht_applicable': True, 'is_resident_of_spanish_islands': None, 'wht_rate_override': None } @pytest.mark.parametrize( ( 'authorize_many_accounts_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standlone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ) ] ) @patch('abacus_account.blueprints.account_tax_info.authorize_many_accounts') def test_get_account_tax_info_by_id( mock_authorize_many_accounts: MagicMock, fixture_client: FlaskClient, authorize_many_accounts_return: bool, profile_type: str, profile_role: str, expected_status_code: int): """Get /account-tax-info/:id.""" account_tax_info = AccountTaxInfoFactory.create() mock_authorize_many_accounts.return_value = authorize_many_accounts_return res = fixture_client.get( f'/account-tax-info/{account_tax_info.account_tax_info_id}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus' } ) assert res.status_code == expected_status_code if expected_status_code == 403: assert res.json['message'] == 'Unauthorized' assert res.json['code'] == error.ERROR_CODE_AUTHORIZATION else: assert res.json == { 'account_tax_info_id': account_tax_info.account_tax_info_id, 'account_id': account_tax_info.account_id, 'country_of_tax_residence': account_tax_info.country_of_tax_residence, 'is_sba_signed': account_tax_info.is_sba_signed, 'is_vat_exempt': account_tax_info.is_vat_exempt, 'is_tax_treaty_claimed': account_tax_info.is_tax_treaty_claimed, 'tax_employment_type': account_tax_info.tax_employment_type, 'certificate_of_residence_expiration_date': account_tax_info.certificate_of_residence_expiration_date, 'is_wht_applicable': account_tax_info.is_wht_applicable, 'is_resident_of_spanish_islands': account_tax_info.is_resident_of_spanish_islands, 'wht_rate_override': account_tax_info.wht_rate_override } @pytest.mark.parametrize( ( 'authorize_many_accounts_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standlone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ) ] ) @patch('abacus_account.blueprints.account_tax_info.authorize_many_accounts') def test_get_account_tax_info_account_by_id( mock_authorize_many_accounts: MagicMock, fixture_client: FlaskClient, authorize_many_accounts_return: bool, profile_type: str, profile_role: str, expected_status_code: int): """Get /account/:id/account-tax-info.""" account_tax_info = AccountTaxInfoFactory.create() mock_authorize_many_accounts.return_value = authorize_many_accounts_return res = fixture_client.get( f'/account/{account_tax_info.account_id}/account-tax-info', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus' } ) assert res.status_code == expected_status_code if expected_status_code == 403: assert res.json['message'] == 'Unauthorized' assert res.json['code'] == error.ERROR_CODE_AUTHORIZATION else: assert res.json == { 'account_tax_info_id': account_tax_info.account_tax_info_id, 'account_id': account_tax_info.account_id, 'country_of_tax_residence': account_tax_info.country_of_tax_residence, 'is_sba_signed': account_tax_info.is_sba_signed, 'is_vat_exempt': account_tax_info.is_vat_exempt, 'is_tax_treaty_claimed': account_tax_info.is_tax_treaty_claimed, 'tax_employment_type': account_tax_info.tax_employment_type, 'certificate_of_residence_expiration_date': account_tax_info.certificate_of_residence_expiration_date, 'is_wht_applicable': account_tax_info.is_wht_applicable, 'is_resident_of_spanish_islands': account_tax_info.is_resident_of_spanish_islands, 'wht_rate_override': account_tax_info.wht_rate_override } def test_get_account_tax_info_snapshot_tsv(fixture_client): """Test to get account tax info in tsv format.""" account_1 = AccountFactory.create(account_id=1) account_2 = AccountFactory.create(account_id=2) AccountTaxInfoFactory.create(account_tax_info_id=11, account=account_1) AccountTaxInfoFactory.create(account_tax_info_id=12, account=account_2) result = fixture_client.post('/account-tax-info/snapshot', json=[]) assert result.status_code == 200 assert result.data.decode() == \ 'account_tax_info_id\taccount_id\tcountry_of_tax_residence\t' \ 'is_sba_signed\tis_vat_exempt\tis_tax_treaty_claimed\ttax_employment_type\t' \ 'certificate_of_residence_expiration_date\tis_wht_applicable\t' \ 'is_resident_of_spanish_islands\twht_rate_override\n' \ '11\t1\tUSA\t0\t1\t0\t\t\t1\t\t\n' \ '12\t2\tUSA\t0\t1\t0\t\t\t1\t\t\n' def test_get_account_tax_info_snapshot_tsv_filtered(account_fixtures, fixture_client): """Test to get account tax info in tsv format.""" for account in account_fixtures: account_tax_info_id = 200 + account.account_id AccountTaxInfoFactory.create( account_tax_info_id=account_tax_info_id, account=account ) result = fixture_client.post('/account-tax-info/snapshot', json=[1, 3]) assert result.status_code == 200 assert result.data.decode() == \ 'account_tax_info_id\taccount_id\tcountry_of_tax_residence\t' \ 'is_sba_signed\tis_vat_exempt\tis_tax_treaty_claimed\ttax_employment_type\t' \ 'certificate_of_residence_expiration_date\tis_wht_applicable\t' \ 'is_resident_of_spanish_islands\twht_rate_override\n' \ '201\t1\tUSA\t0\t1\t0\t\t\t1\t\t\n' \ '203\t3\tUSA\t0\t1\t0\t\t\t1\t\t\n' def test_get_account_tax_info_list_success( fixture_client, account_fixtures, faker ): """Test to get get_account_tax_info_list.""" test_expiration_date = faker.past_date() for account in account_fixtures: AccountTaxInfoFactory.create( account=account, certificate_of_residence_expiration_date=test_expiration_date ) res = fixture_client.post( '/accounts/account-tax-info?limit=3&offset=1' f'&certificate_of_residence_expiration_date_start={test_expiration_date}' f'&certificate_of_residence_expiration_date_end={test_expiration_date}', json=[1, 2, 3, 4] ) assert res.status_code == 200 assert res.json['total_count'] == 4 assert [item['account_id'] for item in res.json['items']] == [2, 3, 4] def test_get_account_tax_info_list_failure( fixture_client, account_fixtures ): """Test to get get_account_tax_info_list failure on validation.""" for account in account_fixtures: AccountTaxInfoFactory.create(account=account) res = fixture_client.post( '/accounts/account-tax-info?limit=3&offset=1' '&certificate_of_residence_expiration_date_start=wrong-date' '&certificate_of_residence_expiration_date_end=wrong-date', json=['1a', '2b'] ) assert res.status_code == 400 assert res.json == { 'code': 'error', 'message':{ 'account_ids': { '0': ['Must be an integer greater or equal to 0.'], '1': ['Must be an integer greater or equal to 0.'] }, 'certificate_of_residence_expiration_date_end': [ 'Must be a date in YYYY-MM-DD format.' ], 'certificate_of_residence_expiration_date_start': [ 'Must be a date in YYYY-MM-DD format.' ] } } res = fixture_client.post( '/accounts/account-tax-info?limit=3a&offset=1b' ) assert res.status_code == 415