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 @@ -41,10 +41,16 @@ def validate(business: Business, filing: dict) -> Error | None:
agm_year_path: Final = "/filing/agmLocationChange/year"
year = get_int(filing, agm_year_path)
if year:
expected_min = LegislationDatetime.now().year - 2
expected_max = LegislationDatetime.now().year + 1
current_year = LegislationDatetime.now().year
# AGM year can never be before the year the business was founded, even if that is
# more recent than the default 2-year lookback window.
founding_year = LegislationDatetime.as_legislation_timezone(business.founding_date).year \
if business.founding_date else current_year - 2
expected_min = max(current_year - 2, founding_year)
expected_max = current_year + 1
if expected_min > year or year > expected_max:
msg.append({"error": "AGM year must be between -2 or +1 year from current year.", "path": agm_year_path})
msg.append({"error": f"AGM year must be between {expected_min} and {expected_max}.",
"path": agm_year_path})

# A non-empty reason (at least one non-whitespace character) is enforced by the schema
# (business-schemas agm_location_change reason pattern).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,48 @@
# rejected by schema validation (HTTP 422) instead of the legal-api business check (HTTP 400).
SCHEMA_REJECTED = 'SCHEMA_REJECTED'

# Set far enough in the past that founding date never becomes the binding floor
OLD_FOUNDING_DATE = datetime.utcnow().replace(year=datetime.utcnow().year - 10)


@pytest.mark.parametrize(
'test_name, expected_code, message',
[
('INVALID_YEAR', HTTPStatus.UNPROCESSABLE_ENTITY, SCHEMA_REJECTED),
('FAIL_YEAR-3', HTTPStatus.BAD_REQUEST, 'AGM year must be between -2 or +1 year from current year.'),
('FAIL_YEAR+2', HTTPStatus.BAD_REQUEST, 'AGM year must be between -2 or +1 year from current year.'),
('FAIL_YEAR-3', HTTPStatus.BAD_REQUEST, None),
('FAIL_YEAR+2', HTTPStatus.BAD_REQUEST, None),
('SUCCESS-2', None, None),
('SUCCESS+1', None, None),
('SUCCESS', None, None)
]
)
def test_validate_agm_year(session, mocker, test_name, expected_code, message, monkeypatch):
"""Assert validate agm year."""
"""Assert validate agm year for an established business (founding date well outside the lookback window)."""
monkeypatch.setattr(
'legal_api.services.flags.value',
lambda flag, default=None: "BC BEN CC ULC C CBEN CCC CUL" if flag == 'supported-agm-location-change-entities' else default
)
business = factory_business(identifier='BC1234567', entity_type='BC', founding_date=datetime.utcnow())
business = factory_business(identifier='BC1234567', entity_type='BC', founding_date=OLD_FOUNDING_DATE)
filing = copy.deepcopy(FILING_HEADER)
filing['filing']['agmLocationChange'] = copy.deepcopy(AGM_LOCATION_CHANGE)
filing['filing']['header']['name'] = 'agmLocationChange'

current_year = LegislationDatetime.now().year
expected_min = current_year - 2
expected_max = current_year + 1

if test_name == 'INVALID_YEAR':
filing['filing']['agmLocationChange']['year'] = 'invalid'
elif test_name == 'FAIL_YEAR-3':
filing['filing']['agmLocationChange']['year'] = str(LegislationDatetime.now().year - 3)
filing['filing']['agmLocationChange']['year'] = str(current_year - 3)
elif test_name == 'FAIL_YEAR+2':
filing['filing']['agmLocationChange']['year'] = str(LegislationDatetime.now().year + 2)
filing['filing']['agmLocationChange']['year'] = str(current_year + 2)
elif test_name == 'SUCCESS-2':
filing['filing']['agmLocationChange']['year'] = str(LegislationDatetime.now().year - 2)
filing['filing']['agmLocationChange']['year'] = str(current_year - 2)
elif test_name == 'SUCCESS+1':
filing['filing']['agmLocationChange']['year'] = str(LegislationDatetime.now().year + 1)
filing['filing']['agmLocationChange']['year'] = str(current_year + 1)
elif test_name == 'SUCCESS':
filing['filing']['agmLocationChange']['year'] = str(LegislationDatetime.now().year)
filing['filing']['agmLocationChange']['year'] = str(current_year)
err = validate(business, filing)

# validate outcomes
Expand All @@ -71,11 +78,54 @@ def test_validate_agm_year(session, mocker, test_name, expected_code, message, m
assert err.code == HTTPStatus.UNPROCESSABLE_ENTITY
elif not test_name.startswith('SUCCESS'):
assert expected_code == err.code
if message:
assert message == err.msg[0]['error']
assert f'AGM year must be between {expected_min} and {expected_max}.' == err.msg[0]['error']
else:
assert not err


@pytest.mark.parametrize(
'test_name, founding_years_ago, year_offset_from_now',
[
# business founded less than 2 years ago: founding year should raise the floor
# above the default lookback year
('FAIL_BEFORE_FOUNDING_YEAR', 1, -2),
('SUCCESS_AT_FOUNDING_YEAR', 1, -1),
# business founded this year: floor should equal the current year
('FAIL_BEFORE_FOUNDING_THIS_YEAR', 0, -1),
('SUCCESS_FOUNDING_THIS_YEAR', 0, 0),
]
)
def test_validate_agm_year_founding_date_floor(
session, mocker, test_name, founding_years_ago, year_offset_from_now, monkeypatch
):
"""Assert AGM year cannot be set to a year before the business's founding year."""
monkeypatch.setattr(
'legal_api.services.flags.value',
lambda flag, default=None: "BC BEN CC ULC C CBEN CCC CUL" if flag == 'supported-agm-location-change-entities' else default
)
current_year = LegislationDatetime.now().year
founding_date = datetime.utcnow().replace(year=current_year - founding_years_ago)
business = factory_business(identifier='BC1234567', entity_type='BC', founding_date=founding_date)

filing = copy.deepcopy(FILING_HEADER)
filing['filing']['agmLocationChange'] = copy.deepcopy(AGM_LOCATION_CHANGE)
filing['filing']['header']['name'] = 'agmLocationChange'
filing['filing']['agmLocationChange']['year'] = str(current_year + year_offset_from_now)

err = validate(business, filing)

founding_year = current_year - founding_years_ago
expected_min = max(current_year - 2, founding_year)
expected_max = current_year + 1

if test_name.startswith('FAIL'):
assert err is not None
assert err.code == HTTPStatus.BAD_REQUEST
assert f'AGM year must be between {expected_min} and {expected_max}.' == err.msg[0]['error']
else:
assert not err


@pytest.mark.parametrize(
'test_name, reason, expected_code, message',
[
Expand All @@ -91,7 +141,7 @@ def test_validate_agm_reason(session, mocker, test_name, reason, expected_code,
'legal_api.services.flags.value',
lambda flag, default=None: "BC BEN CC ULC C CBEN CCC CUL" if flag == 'supported-agm-location-change-entities' else default
)
business = factory_business(identifier='BC1234567', entity_type='BC', founding_date=datetime.utcnow())
business = factory_business(identifier='BC1234567', entity_type='BC', founding_date=OLD_FOUNDING_DATE)
filing = copy.deepcopy(FILING_HEADER)
filing['filing']['agmLocationChange'] = copy.deepcopy(AGM_LOCATION_CHANGE)
filing['filing']['header']['name'] = 'agmLocationChange'
Expand Down