"""Test tax details logic.""" from unittest.mock import call, MagicMock, patch import pytest from payee.constants.constants import PAYEE_EVENT_NAMES from payee.constants.error import ERROR_OWS_HEADERS from payee.logic.exceptions import LogicError from payee.logic.tax_details import ( create_tax_details, delete_record, get_current_tax_details, resync_payment_readiness, save_tax_details, ) from payee.models.tax_details import TaxDetailsDocument from payee.utils.exception import OwsRequestHeadersException ua_alpha2 = 'UA' ua_alpha3 = 'UKR' us_alpha2 = 'US' us_alpha3 = 'USA' @patch('payee.logic.tax_details.get_audit_fields') @patch('payee.logic.secure_document.flask_request.get_ows_headers') @patch('payee.logic.secure_document.current_timestamp') @patch('payee.logic.tax_details.save_tax_details') @patch('payee.logic.tax_details.emit_payee_event', return_value=True) def test_create_payment_details( mock_emit, mock_save_tax_details, mock_current_timestamp, mock_ows_headers, mock_audit_fields, mock_config, mock_datetime_object, mock_payee_vat_registered_tax_details, mock_payee_vat_registered_tax_details_flattened, mock_headers, monkeypatch, ): """Test successfully creating tax details.""" account_payee_id = 123 audit_fields = { 'modified_at': '2022-05-04T12:16:57.474487', 'modified_by_identity': 'aksjKJASD66340ooOHSDA)D!d1s', 'modified_by_profile_id': '90000020', 'modified_by_profile_type': 'AbacusProfile', } mock_secure_doc = TaxDetailsDocument( { **mock_payee_vat_registered_tax_details_flattened, **audit_fields, # 'revision': 'tax_details#0', # 'modified_by': None, } ) mock_save_tax_details.return_value = mock_secure_doc mock_kafka_producers = { PAYEE_EVENT_NAMES.VAT_COLLECTED: MagicMock(produce_event=MagicMock()), } monkeypatch.setattr( 'payee.config.Config.KAFKA_PRODUCERS_BY_ACTION_NAME', mock_kafka_producers ) mock_current_timestamp.return_value = mock_datetime_object mock_ows_headers.return_value = mock_headers mock_audit_fields.return_value = audit_fields params = { **mock_payee_vat_registered_tax_details_flattened, 'country_code': ua_alpha2, 'country_of_tax_residency_code': us_alpha2, } res = create_tax_details( mock_config.SDM_CONFIG, account_payee_id=account_payee_id, **params ) assert res == { 'account_payee_id': account_payee_id, **mock_payee_vat_registered_tax_details, **audit_fields, 'local_tax_id': None, 'revision': '0', 'modified_by': None, } mock_save_tax_details.assert_called_once_with( account_payee_id, mock_config.SDM_CONFIG, **params, **audit_fields, ) mock_emit.assert_called_once_with( account_payee_id=account_payee_id, action_name=PAYEE_EVENT_NAMES.VAT_COLLECTED, ) @patch('payee.logic.tax_details.SecureDocumentManager') @patch('payee.logic.tax_details.TaxDetailsDocument') @patch('payee.logic.tax_details.get_secure_document_manager') def test_save_tax_details( mock_get_sdm, mock_tax_details_doc, mock_sdm, mock_config, mock_payee_vat_registered_tax_details, ): """Test successfully saving tax details.""" account_payee_id = 1 params = mock_payee_vat_registered_tax_details mock_get_sdm.return_value = mock_sdm secure_doc = mock_tax_details_doc(params) secure_doc.field_with_value_exists.return_value = False res = save_tax_details(account_payee_id, mock_config.SDM_CONFIG, **params) assert isinstance(res, type(secure_doc)) mock_get_sdm.assert_called_once_with(mock_config.SDM_CONFIG) mock_sdm.save_item.assert_called_once_with( secure_doc.owner_type(), account_payee_id, secure_doc ) @patch('payee.logic.tax_details.build_tax_details_response') @patch('payee.logic.tax_details.SecureDocumentManager') @patch('payee.logic.tax_details.get_secure_document_manager') def test_get_current_tax_details( mock_get_sdm, mock_sdm, mock_build_tax_details_response, mock_config ): """Test successfully retrieving tax details.""" account_payee_id = 123 mock_item = 'mock item' mock_tax_details_response = {'something': True, 'else': False, 'key': 'value'} mock_get_sdm.return_value = mock_sdm mock_sdm.get_item.return_value = mock_item mock_build_tax_details_response.return_value = mock_tax_details_response res = get_current_tax_details(mock_config.SDM_CONFIG, account_payee_id) assert res == mock_tax_details_response mock_get_sdm.assert_called_once_with(mock_config.SDM_CONFIG) mock_sdm.get_item.assert_called_once_with( 'Payee', account_payee_id, TaxDetailsDocument ) mock_build_tax_details_response.assert_called_once_with(account_payee_id, mock_item) @patch('payee.logic.secure_document.flask_request.get_ows_headers', return_value={}) @patch('payee.logic.tax_details.SecureDocumentManager') @patch('payee.logic.tax_details.get_secure_document_manager') def test_save_tax_details_headers_error( mock_get_sdm, mock_sdm, mock_get_headers, mock_config, mock_payee_vat_registered_tax_details, ): """Test saving tax details error on missing headers.""" params = mock_payee_vat_registered_tax_details mock_get_sdm.return_value = mock_sdm with pytest.raises(OwsRequestHeadersException) as excinfo: create_tax_details(mock_config.SDM_CONFIG, **params) assert str(excinfo.value) == ERROR_OWS_HEADERS @patch('payee.logic.tax_details.emit_payee_event', return_value=True) def test_resync_payment_readiness(mock_emit, monkeypatch): """Test resync_payment_readiness.""" mock_kafka_producers = { PAYEE_EVENT_NAMES.RESYNC_PAYMENT_READINESS: MagicMock( produce_event=MagicMock() ), } monkeypatch.setattr( 'payee.config.Config.KAFKA_PRODUCERS_BY_ACTION_NAME', mock_kafka_producers ) account_payee_id = 123 message = resync_payment_readiness(account_payee_id=account_payee_id) mock_emit.assert_called_once_with( account_payee_id=account_payee_id, action_name=PAYEE_EVENT_NAMES.RESYNC_PAYMENT_READINESS, ) assert message == {'account_payee_id': account_payee_id} @patch('payee.logic.tax_details.get_secure_document_manager') @patch('payee.logic.tax_details.save_secure_document_details_version') @patch('payee.logic.tax_details.has_tax_details') def test_delete_record_success( mock_has_tax_details, mock_save_secure_document_details_version, mock_get_secure_document_manager, ): """Test successful soft delete of tax details.""" account_payee_id = 123 revision_id = 'tax_details#1' # mock existing document mock_doc = MagicMock(spec=TaxDetailsDocument) mock_doc.owner_type.return_value = 'Payee' mock_doc.values = {'field': 'value'} mock_doc.__class__ = TaxDetailsDocument mock_has_tax_details.return_value = mock_doc # mock revision creation mock_save_secure_document_details_version.return_value = revision_id # mock sdm and its delete_current_item mock_sdm = MagicMock() mock_get_secure_document_manager.return_value = mock_sdm res_revision_id, res_document = delete_record(account_payee_id) assert res_revision_id == revision_id assert res_document == mock_doc assert mock_has_tax_details.call_args_list == [call(account_payee_id)] assert mock_save_secure_document_details_version.call_args_list == [ call( account_payee_id, TaxDetailsDocument, **mock_doc.values, ) ] assert mock_get_secure_document_manager.called assert mock_sdm.delete_current_item.call_args_list == [ call( mock_doc.owner_type(), account_payee_id, TaxDetailsDocument, ) ] @patch('payee.logic.tax_details.has_tax_details', return_value=None) def test_delete_record_document_not_found(mock_has_tax_details): """Test delete_record raises when document does not exist.""" account_payee_id = 123 with pytest.raises(LogicError, match='Document was not found'): delete_record(account_payee_id) assert mock_has_tax_details.call_args_list == [call(account_payee_id)]