"""Tests for tax from info schema.""" import datetime from marshmallow import ValidationError import pytest from payee.constants.constants import TAX_FORM_TYPES from payee.schemas.tax_form import ( FilterParamsPostSchema, TaxFormInfoDetailsOutputSchema, TaxFormInfoOutputSchema, TaxFormInfoSchema, TaxFormInputSchema, USTaxFormW8BENESchema, ) from tests.constants import MOCK_TAX_FORM_DETAILS from tests.utils.factories import TaxFormInfoDetailsFactory, TaxFormInfoFactory def test_tax_form_info_schema(): """Test tax form info schema.""" w8_tax_form_info = TaxFormInfoFactory.build(tax_form_type=TAX_FORM_TYPES.W8BEN) result = TaxFormInfoSchema().dump(w8_tax_form_info) assert result == { 'account_payee_tax_form_info_id': 1, 'tax_form_type': 'W8BEN', 'account_payee_id': 1, 'signed_date': '2024-02-01', 'expiration_date': str(w8_tax_form_info.expiration_date), 'last_modified': '2024-02-01', } w9_tax_form_info = TaxFormInfoFactory.build( signed_date=None, expiration_date=None, tax_form_type=TAX_FORM_TYPES.W9 ) result = TaxFormInfoSchema().dump(w9_tax_form_info) assert result == { 'account_payee_tax_form_info_id': 1, 'tax_form_type': 'W9', 'account_payee_id': 1, 'signed_date': None, 'expiration_date': None, 'last_modified': '2024-02-01', } def test_tax_form_info_output_schema(): """Test tax form info output schema.""" w8_tax_form_info = TaxFormInfoFactory.build(tax_form_type=TAX_FORM_TYPES.W8BEN) w9_tax_form_info = TaxFormInfoFactory.build( account_payee_tax_form_info_id=2, signed_date=None, expiration_date=None, tax_form_type=TAX_FORM_TYPES.W9, account_payee_id=2, ) output = { 'items': [ w8_tax_form_info, w9_tax_form_info, ], 'total_count': 2, } result = TaxFormInfoOutputSchema().dump(output) assert result == { 'items': [ { 'account_payee_tax_form_info_id': 1, 'tax_form_type': 'W8BEN', 'account_payee_id': 1, 'signed_date': '2024-02-01', 'expiration_date': str(w8_tax_form_info.expiration_date), 'last_modified': '2024-02-01', }, { 'account_payee_tax_form_info_id': 2, 'tax_form_type': 'W9', 'account_payee_id': 2, 'signed_date': None, 'expiration_date': None, 'last_modified': '2024-02-01', }, ], 'total_count': 2, } def test_filter_params_post_schema(): """Test filter params post schema.""" filter_params = { 'is_active': True, 'expiration_date_start': '2024-11-30', 'expiration_date_end': '2027-11-30', 'account_payee_ids': [1, 2, 3], } result = FilterParamsPostSchema().load(filter_params) assert result == { 'is_active': True, 'expiration_date_start': datetime.date(2024, 11, 30), 'expiration_date_end': datetime.date(2027, 11, 30), 'account_payee_ids': [1, 2, 3], } filter_params = {} result = FilterParamsPostSchema().load(filter_params) assert result == {} def test_filter_params_post_schema_invalid(): filter_params = { 'is_active': True, 'expiration_date_start': '2027-11-30', 'expiration_date_end': '2024-11-30', 'account_payee_ids': [1, 2, 3], } with pytest.raises(ValidationError) as excinfo: FilterParamsPostSchema().load(filter_params) assert excinfo.value.messages == { '_schema': ['expiration_date_start must be before expiration_date_end'] } def test_tax_form_info_details_output_schema(): """Test tax form info details output schema.""" items = [ TaxFormInfoDetailsFactory.build( account_payee_tax_form_info_id=index, tax_form_type=tax_form_type ) for index, tax_form_type in enumerate(MOCK_TAX_FORM_DETAILS.keys(), 1) ] output = { 'items': items, 'total_count': 1, } result = TaxFormInfoDetailsOutputSchema().dump(output) expected_items = [] for index, (tax_form_type, details) in enumerate(MOCK_TAX_FORM_DETAILS.items(), 1): expected_items.append( { 'account_payee_tax_form_info_id': index, 'tax_form_type': tax_form_type, 'account_payee_id': 1, 'signed_date': '2024-02-01', 'expiration_date': str( datetime.date.today() + datetime.timedelta(days=1) ), 'last_modified': '2024-02-01', **details, } ) assert result == { 'items': expected_items, 'total_count': 1, } @pytest.mark.parametrize( 'tax_form_type, details_fixture', MOCK_TAX_FORM_DETAILS.items() ) def test_tax_form_input_schema_load_success(tax_form_type, details_fixture, faker): signed_date = faker.past_date() result = TaxFormInputSchema().load( { **details_fixture, 'tax_form_type': tax_form_type, 'signed_date': str(signed_date), } ) assert result == { **details_fixture, 'tax_form_type': tax_form_type, 'signed_date': signed_date, } @pytest.mark.parametrize( 'tax_form_type, details_fixture', MOCK_TAX_FORM_DETAILS.items() ) def test_tax_form_input_schema_load_failure(tax_form_type, details_fixture): with pytest.raises(ValidationError) as exc_info: TaxFormInputSchema().load({}) assert exc_info.value.messages == { 'tax_form_type': ['Missing data for required field.'] } with pytest.raises(ValidationError) as exc_info: TaxFormInputSchema().load({'tax_form_type': tax_form_type}) if tax_form_type == TAX_FORM_TYPES.W9: assert set(exc_info.value.messages.keys()) == {*details_fixture.keys()} elif tax_form_type == TAX_FORM_TYPES.W8BENE: assert set(exc_info.value.messages.keys()) == { *(k for k in details_fixture.keys() if k != 'lob'), 'signed_date', } else: assert set(exc_info.value.messages.keys()) == { *details_fixture.keys(), 'signed_date', } def test_tax_form_w8bene_schema_load_lob_validation(): data = { 'tax_form_type': TAX_FORM_TYPES.W8BENE, 'tax_id_country': 'USA', 'tin_type': 'test tin type', 'tin': 'test tin', 'tax_name': 'test tax name', 'tax_treaty_claim': True, 'type_of_entity': 'test type of entity', 'lob': 'test lob', 'signed_date': str(datetime.datetime.today().date()), 'account_payee_id': 1, } assert USTaxFormW8BENESchema().load(data) == { **data, 'signed_date': datetime.datetime.today().date(), } data = { 'tax_form_type': TAX_FORM_TYPES.W8BENE, 'tax_id_country': 'USA', 'tin_type': 'test tin type', 'tin': 'test tin', 'tax_name': 'test tax name', 'tax_treaty_claim': False, 'type_of_entity': 'test type of entity', 'lob': None, 'signed_date': str(datetime.datetime.today().date()), 'account_payee_id': 1, } assert USTaxFormW8BENESchema().load(data) == { **data, 'signed_date': datetime.datetime.today().date(), } data = { 'tax_form_type': TAX_FORM_TYPES.W8BENE, 'tax_id_country': 'USA', 'tin_type': 'test tin type', 'tin': 'test tin', 'tax_name': 'test tax name', 'tax_treaty_claim': False, 'type_of_entity': 'test type of entity', 'signed_date': str(datetime.datetime.today().date()), 'account_payee_id': 1, } assert USTaxFormW8BENESchema().load(data) == { **data, 'signed_date': datetime.datetime.today().date(), } data = { 'tax_form_type': TAX_FORM_TYPES.W8BENE, 'tax_id_country': 'USA', 'tin_type': 'test tin type', 'tin': 'test tin', 'tax_name': 'test tax name', 'tax_treaty_claim': True, 'type_of_entity': 'test type of entity', 'lob': None, 'signed_date': str(datetime.datetime.today().date()), 'account_payee_id': 1, } with pytest.raises(ValidationError) as exc_info: USTaxFormW8BENESchema().load(data) assert exc_info.value.messages == {'lob': ['lob is required for tax_treaty_claim']} data = { 'tax_form_type': TAX_FORM_TYPES.W8BENE, 'tax_id_country': 'USA', 'tin_type': 'test tin type', 'tin': 'test tin', 'tax_name': 'test tax name', 'tax_treaty_claim': True, 'type_of_entity': 'test type of entity', 'signed_date': str(datetime.datetime.today().date()), 'account_payee_id': 1, } with pytest.raises(ValidationError) as exc_info: USTaxFormW8BENESchema().load(data) assert exc_info.value.messages == {'lob': ['lob is required for tax_treaty_claim']}