"""Unit tests for WorksheetTaxCorrection API.""" from unittest.mock import call, patch from urllib.parse import urlencode import pytest from payment.constants import constants from payment.logic.exceptions import LogicError @patch('payment.blueprints.worksheet_tax_correction.logic') def test_bulk_create_worksheet_tax_correction_success(mock_logic, fixture_client): """Test for bulk_create_worksheet_tax_correction endpoint.""" post_data = ( { 'contract_id': 1, 'account_id': 1, 'correction_statement_period_id': 1, 'payable_detail_type_id': 1, 'amount': 10.00, 'currency_code': 'USD', 'note': 'test note 1', }, { 'contract_id': 2, 'account_id': 2, 'correction_statement_period_id': 2, 'payable_detail_type_id': 2, 'amount': 20.00, 'currency_code': 'GBP', 'note': 'test note 2', }, ) res = fixture_client.post('/tax-corrections/bulk', json=post_data) assert res.status_code == 201 assert res.json == constants.BULK_ENDPOINT_SUCCESS_RESPONSE assert mock_logic.bulk_create.call_args_list == [call(post_data)] @patch('payment.blueprints.worksheet_tax_correction.logic') def test_bulk_create_worksheet_tax_correction_failure_validation( mock_logic, fixture_client ): """Test for bulk_create_worksheet_tax_correction endpoint failure validation.""" post_data = ( { 'account_id': 1, 'correction_statement_period_id': 1, 'payable_detail_type_id': 1, 'amount': 10.00, 'currency_code': 'USD', 'note': 'test note 1', }, { 'contract_id': 2, 'correction_statement_period_id': 2, 'payable_detail_type_id': 2, 'amount': 20.00, 'currency_code': 'GBP', 'note': 'test note 2', }, ) mock_logic.bulk_create.side_effect = LogicError('Error text') res = fixture_client.post('/tax-corrections/bulk', json=post_data) assert res.status_code == 400 assert res.json == { 'code': 'error', 'message': { 'json': { '0': {'contract_id': ['Must be specified.']}, '1': {'account_id': ['Must be specified.']}, } }, } assert not mock_logic.bulk_create.called @patch('payment.blueprints.worksheet_tax_correction.logic') def test_bulk_create_worksheet_tax_correction_failure_logic(mock_logic, fixture_client): """Test for bulk_create_worksheet_tax_correction endpoint failure logic.""" post_data = ( { 'contract_id': 1, 'account_id': 1, 'correction_statement_period_id': 1, 'payable_detail_type_id': 1, 'amount': 10.00, 'currency_code': 'USD', 'note': 'test note 1', }, { 'contract_id': 2, 'account_id': 2, 'correction_statement_period_id': 2, 'payable_detail_type_id': 2, 'amount': 20.00, 'currency_code': 'GBP', 'note': 'test note 2', }, ) mock_logic.bulk_create.side_effect = LogicError('Error text') res = fixture_client.post('/tax-corrections/bulk', json=post_data) assert res.status_code == 400 assert res.json == {'code': 'error', 'message': 'Error text'} assert mock_logic.bulk_create.call_args_list == [call(post_data)] @pytest.mark.parametrize( ('correction_type', 'correction_status'), ( (constants.CORRECTION_TYPES.WHT, constants.CORRECTION_STATUSES.ACTIVE), (constants.CORRECTION_TYPES.WHT, constants.CORRECTION_STATUSES.PENDING), ), ) @patch('payment.blueprints.worksheet_tax_correction.logic') def test_get_tax_corrections_success( mock_logic, fixture_client, correction_type, correction_status, faker ): """Test for get_tax_corrections endpoint.""" correction_statement_period_id = faker.pyint() contract_ids = faker.pylist(value_types=[int]) limit = faker.pyint(min_value=1, max_value=300) offset = faker.pyint() params = { 'limit': limit, 'offset': offset, } body = { 'filters': { 'correction_statement_period_id': correction_statement_period_id, 'contract_ids': contract_ids, } } mock_worksheets = [ { 'worksheet_tax_correction_id': 1, 'contract_id': 1, 'account_id': 1, 'correction_statement_period_id': 1, 'payable_detail_type_id': 1, 'amount': '10.00', 'currency_code': 'USD', 'note': 'test note 1', }, { 'worksheet_tax_correction_id': 2, 'contract_id': 2, 'account_id': 2, 'correction_statement_period_id': 2, 'payable_detail_type_id': 2, 'amount': '20.00', 'currency_code': 'GBP', 'note': 'test note 2', }, ] mock_result = {'items': mock_worksheets, 'total_count': len(mock_worksheets)} mock_logic.get_tax_corrections.return_value = mock_result res = fixture_client.post( f'/tax-corrections/{correction_type}/{correction_status}' f'/?{urlencode(params)}', json=body, ) assert res.status_code == 200, res.text assert res.json == mock_result assert mock_logic.get_tax_corrections.call_args_list == [ call( correction_type=correction_type, correction_status=correction_status, limit=limit, offset=offset, **body['filters'], ) ] mock_logic.get_tax_corrections.reset_mock() res = fixture_client.post(f'/tax-corrections/{correction_type}/{correction_status}') assert res.status_code == 200, res.text assert res.json == mock_result assert mock_logic.get_tax_corrections.call_args_list == [ call( correction_type=correction_type, correction_status=correction_status, limit=constants.DEFAULT_PAGE_LIMIT, offset=constants.DEFAULT_PAGE_OFFSET, ) ] @pytest.mark.parametrize( ('correction_type', 'correction_status'), ( (constants.CORRECTION_TYPES.WHT, constants.CORRECTION_STATUSES.ACTIVE), (constants.CORRECTION_TYPES.WHT, constants.CORRECTION_STATUSES.PENDING), ), ) @patch('payment.blueprints.worksheet_tax_correction.logic') def test_get_tax_corrections_failure( mock_logic, fixture_client, correction_type, correction_status, faker ): """Test for get_tax_corrections endpoint failure validation.""" correction_statement_period_id = 'noint' contract_ids = ['noint'] limit = 'noint' offset = 'noint' params = { 'limit': limit, 'offset': offset, } body = { 'filters': { 'correction_statement_period_id': correction_statement_period_id, 'contract_ids': contract_ids, } } res = fixture_client.post( f'/tax-corrections/{correction_type}/{correction_status}' f'/?{urlencode(params)}', json=body, ) assert res.status_code == 400, res.text assert res.json == { 'code': 'error', 'message': { 'query': { 'limit': ['Not a valid integer.'], 'offset': ['Not a valid integer.'], } }, } assert not mock_logic.get_tax_corrections.called res = fixture_client.post( f'/tax-corrections/{correction_type}/{correction_status}', json=body ) assert res.status_code == 400, res.text assert res.json == { 'code': 'error', 'message': { 'json': { 'filters': { 'contract_ids': { '0': ['Must be an integer greater or ' 'equal to 0.'] }, 'correction_statement_period_id': [ 'Must be an integer ' 'greater or equal to ' '0.' ], } } }, } assert not mock_logic.get_tax_corrections.called @patch( 'payment.blueprints.worksheet_tax_correction.logic.delete_worksheet_tax_corrections' # noqa: E501 ) def test_delete_by_worksheet_tax_correction_ids(mock_logic, fixture_client): """Test delete worksheet_tax_correction by ids.""" mock_logic.return_value = None json_body = {'worksheet_tax_correction_ids': [1, 3]} res = fixture_client.delete('/tax-corrections/bulk/', json=json_body) assert res.status_code == 204 assert mock_logic.call_args_list == [call(worksheet_tax_correction_ids=[1, 3])]