Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def validate_dissolution_parties_address(filing_json, legal_type, dissolution_ty

msg = []
msg.extend(_validate_custodian_email(custodians, dissolution_type, legal_type))
msg.extend(validate_custodian_org_name(custodians, dissolution_type, legal_type))
msg.extend(_validate_custodian_name(custodians, dissolution_type, legal_type))
msg.extend(_validate_address_location(custodians, legal_type))

return msg or None
Expand Down Expand Up @@ -379,18 +379,16 @@ def _validate_custodian_email(parties, dissolution_type, legal_type) -> list:
})
return msg

def validate_custodian_org_name(parties, dissolution_type, legal_type) -> list:
"""Validate custodian organization name of the dissolution filing and trim it."""
def _validate_custodian_name(parties, dissolution_type, legal_type) -> list:
"""Validate custodian name of the dissolution filing and trim it."""
# Only validate for CORP voluntary dissolution
if not (legal_type in Business.CORPS and dissolution_type == DissolutionTypes.VOLUNTARY.value):
return []

msg = []
for idx, party in enumerate(parties):
party_type = get_str(party, "/officer/partyType")
# Only validate if partyType is organization
if party_type == "organization":

org_name = get_str(party, "/officer/organizationName")
stripped_org_name = org_name.strip()

Expand All @@ -405,6 +403,20 @@ def validate_custodian_org_name(parties, dissolution_type, legal_type) -> list:
"path": f"/filing/dissolution/parties/{idx}/officer/organizationName"
})

else:
first_name = get_str(party, "/officer/firstName")

if first_name is None or not first_name.strip():
msg.append({
"error": "Custodian first name is required.",
"path": f"/filing/dissolution/parties/{idx}/officer/firstName"
})
elif first_name != first_name.strip():
msg.append({
"error": "Custodian first name cannot have leading or trailing spaces.",
"path": f"/filing/dissolution/parties/{idx}/officer/firstName"
})

return msg

def _check_dissolution_permission(required_permission: str, dissolution_type: str, filing_type: str) -> Optional[Error]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,36 +510,54 @@ def test_dissolution_custodian_email(session, test_status, legal_type, dissoluti
assert err is None

@pytest.mark.parametrize(
'test_status, legal_type, dissolution_type, party_type, org_name, expected_code, expected_msg',
'test_status, legal_type, dissolution_type, party_type, org_name, first_name, expected_code, expected_msg',
[
# Required organization name cases
('FAIL', 'BC', 'voluntary', 'organization', '', HTTPStatus.BAD_REQUEST,
('FAIL', 'BC', 'voluntary', 'organization', '', None, HTTPStatus.BAD_REQUEST,
'Organization name is required.'),
('FAIL', 'BC', 'voluntary', 'organization', ' ', HTTPStatus.BAD_REQUEST,
('FAIL', 'BC', 'voluntary', 'organization', ' ', None, HTTPStatus.BAD_REQUEST,
'Organization name is required.'),

# Leading/trailing whitespace
('FAIL', 'BC', 'voluntary', 'organization', ' LeadingSpace', HTTPStatus.BAD_REQUEST,
# Leading/trailing whitespace - organization
('FAIL', 'BC', 'voluntary', 'organization', ' LeadingSpace', None, HTTPStatus.BAD_REQUEST,
'Organization name cannot have leading or trailing spaces.'),
('FAIL', 'BC', 'voluntary', 'organization', 'TrailingSpace ', HTTPStatus.BAD_REQUEST,
('FAIL', 'BC', 'voluntary', 'organization', 'TrailingSpace ', None, HTTPStatus.BAD_REQUEST,
'Organization name cannot have leading or trailing spaces.'),
('FAIL', 'BC', 'voluntary', 'organization', ' BothSides ', HTTPStatus.BAD_REQUEST,
('FAIL', 'BC', 'voluntary', 'organization', ' BothSides ', None, HTTPStatus.BAD_REQUEST,
'Organization name cannot have leading or trailing spaces.'),

# Valid name
('SUCCESS', 'BC', 'voluntary', 'organization', 'Test Org', None, None),
# Valid organization name
('SUCCESS', 'BC', 'voluntary', 'organization', 'Test Org', None, None, None),

# Non-organization party types should skip validation
('SUCCESS', 'BC', 'voluntary', 'person', None, None, None),
# Required first name cases
('FAIL', 'BC', 'voluntary', 'person', None, '', HTTPStatus.BAD_REQUEST,
'Custodian first name is required.'),
('FAIL', 'BC', 'voluntary', 'person', None, ' ', HTTPStatus.BAD_REQUEST,
'Custodian first name is required.'),
('FAIL', 'BC', 'voluntary', 'person', None, None, HTTPStatus.BAD_REQUEST,
'Custodian first name is required.'),

# Leading/trailing whitespace - person
('FAIL', 'BC', 'voluntary', 'person', None, ' LeadingSpace', HTTPStatus.BAD_REQUEST,
'Custodian first name cannot have leading or trailing spaces.'),
('FAIL', 'BC', 'voluntary', 'person', None, 'TrailingSpace ', HTTPStatus.BAD_REQUEST,
'Custodian first name cannot have leading or trailing spaces.'),
('FAIL', 'BC', 'voluntary', 'person', None, ' BothSides ', HTTPStatus.BAD_REQUEST,
'Custodian first name cannot have leading or trailing spaces.'),

# Valid first name
('SUCCESS', 'BC', 'voluntary', 'person', None, 'Test Person', None, None),

# Legal types other than CORP should skip validation
('SUCCESS', 'CP', 'voluntary', 'organization', None, None, None),
('SUCCESS', 'BC', 'administrative', 'organization', None, None, None),
('SUCCESS', 'CP', 'voluntary', 'organization', None, None, None, None),
('SUCCESS', 'BC', 'administrative', 'organization', None, None, None, None),
('SUCCESS', 'CP', 'voluntary', 'person', None, None, None, None),
('SUCCESS', 'BC', 'administrative', 'person', None, None, None, None),
]
)
def test_dissolution_custodian_org_name(session, test_status, legal_type, dissolution_type,
party_type, org_name, expected_code, expected_msg):
"""Test custodian organization name validation and trimming."""
def test_dissolution_custodian_name(session, test_status, legal_type, dissolution_type,
party_type, org_name, first_name, expected_code, expected_msg):
"""Test custodian name validation for both person and organization party types."""

business = Business(identifier='BC1234567', legal_type=legal_type)
filing = copy.deepcopy(FILING_HEADER)
Expand All @@ -556,11 +574,15 @@ def test_dissolution_custodian_org_name(session, test_status, legal_type, dissol

officer = filing['filing']['dissolution']['parties'][1]['officer']
officer['partyType'] = party_type

if org_name is not None:
officer['organizationName'] = org_name
elif 'organizationName' in officer:
del officer['organizationName']

if first_name is not None:
officer['firstName'] = first_name

with patch.object(dissolution, 'validate_affidavit', return_value=None), \
patch.object(dissolution, 'validate_dissolution_parties_roles', return_value=None), \
patch('legal_api.services.filings.validations.dissolution.check_good_standing_permission', return_value=None):
Expand Down