Skip to content

Commit

Permalink
21124 Legal API - update allowable actions (bcgov#2716)
Browse files Browse the repository at this point in the history
* Update allowable actions to block voluntary dissolution, alteration and amalgamation filings types

* Add unit tests for allowed filings when business is in dissolution
  • Loading branch information
AimeeGao authored May 27, 2024
1 parent beae9a9 commit 1a99962
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 11 deletions.
37 changes: 26 additions & 11 deletions legal-api/src/legal_api/services/authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class BusinessBlocker(str, Enum):
DRAFT_PENDING = 'DRAFT_PENDING'
NOT_IN_GOOD_STANDING = 'NOT_IN_GOOD_STANDING'
AMALGAMATING_BUSINESS = 'AMALGAMATING_BUSINESS'
IN_DISSOLUTION = 'IN_DISSOLUTION'


class BusinessRequirement(str, Enum):
Expand Down Expand Up @@ -151,7 +152,7 @@ def get_allowable_filings_dict():
'alteration': {
'legalTypes': ['BC', 'BEN', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.DEFAULT]
'business': [BusinessBlocker.DEFAULT, BusinessBlocker.IN_DISSOLUTION]
}
},
'amalgamationApplication': {
Expand All @@ -160,7 +161,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand All @@ -169,7 +171,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand All @@ -178,7 +181,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand Down Expand Up @@ -245,7 +249,9 @@ def get_allowable_filings_dict():
'legalTypes': ['CP', 'BC', 'BEN', 'CC', 'ULC', 'SP', 'GP'],
'blockerChecks': {
'warningTypes': [WarningType.MISSING_REQUIRED_BUSINESS_INFO],
'business': [BusinessBlocker.DEFAULT, BusinessBlocker.NOT_IN_GOOD_STANDING]
'business': [BusinessBlocker.DEFAULT,
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION]
}
},
'administrative': {
Expand Down Expand Up @@ -348,7 +354,7 @@ def get_allowable_filings_dict():
'alteration': {
'legalTypes': ['BC', 'BEN', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.DEFAULT],
'business': [BusinessBlocker.DEFAULT, BusinessBlocker.IN_DISSOLUTION],
'invalidStateFilings': ['restoration.limitedRestoration',
'restoration.limitedRestorationExtension']
}
Expand All @@ -359,7 +365,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand All @@ -368,7 +375,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand All @@ -377,7 +385,8 @@ def get_allowable_filings_dict():
'legalTypes': ['BEN', 'BC', 'ULC', 'CC'],
'blockerChecks': {
'business': [BusinessBlocker.BUSINESS_FROZEN,
BusinessBlocker.NOT_IN_GOOD_STANDING],
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION],
'futureEffectiveFilings': [filing_types_compact.DISSOLUTION_VOLUNTARY,
filing_types_compact.DISSOLUTION_ADMINISTRATIVE]
}
Expand Down Expand Up @@ -424,7 +433,9 @@ def get_allowable_filings_dict():
'legalTypes': ['CP', 'BC', 'BEN', 'CC', 'ULC', 'SP', 'GP'],
'blockerChecks': {
'warningTypes': [WarningType.MISSING_REQUIRED_BUSINESS_INFO],
'business': [BusinessBlocker.DEFAULT, BusinessBlocker.NOT_IN_GOOD_STANDING]
'business': [BusinessBlocker.DEFAULT,
BusinessBlocker.NOT_IN_GOOD_STANDING,
BusinessBlocker.IN_DISSOLUTION]
}
},
},
Expand Down Expand Up @@ -611,7 +622,8 @@ def business_blocker_check(business: Business, is_ignore_draft_blockers: bool =
BusinessBlocker.BUSINESS_FROZEN: False,
BusinessBlocker.DRAFT_PENDING: False,
BusinessBlocker.NOT_IN_GOOD_STANDING: False,
BusinessBlocker.AMALGAMATING_BUSINESS: False
BusinessBlocker.AMALGAMATING_BUSINESS: False,
BusinessBlocker.IN_DISSOLUTION: False
}

if not business:
Expand All @@ -631,6 +643,9 @@ def business_blocker_check(business: Business, is_ignore_draft_blockers: bool =
if business.get_amalgamated_into():
business_blocker_checks[BusinessBlocker.AMALGAMATING_BUSINESS] = True

if business.in_dissolution:
business_blocker_checks[BusinessBlocker.IN_DISSOLUTION] = True

return business_blocker_checks


Expand Down
105 changes: 105 additions & 0 deletions legal-api/tests/unit/services/test_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -2084,6 +2084,111 @@ def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library me
assert allowed_filing_types == expected


@pytest.mark.parametrize(
'test_name,business_exists,state,legal_types,username,roles,expected',
[
# active business - staff user
('staff_active_cp', True, Business.State.ACTIVE, ['CP'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.ADMN_FRZE,
FilingKey.AR_CP,
FilingKey.COA_CP,
FilingKey.COD_CP,
FilingKey.CORRCTN,
FilingKey.COURT_ORDER,
FilingKey.ADM_DISS,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER,
FilingKey.SPECIAL_RESOLUTION])),
('staff_active_corps', True, Business.State.ACTIVE, ['BC', 'BEN', 'CC', 'ULC'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.ADMN_FRZE,
FilingKey.AR_CORPS,
FilingKey.COA_CORPS,
FilingKey.COD_CORPS,
FilingKey.CORRCTN,
FilingKey.COURT_ORDER,
FilingKey.ADM_DISS,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER,
FilingKey.TRANSITION,
])),
('staff_active_llc', True, Business.State.ACTIVE, ['LLC'], 'staff', [STAFF_ROLE], []),
('staff_active_firms', True, Business.State.ACTIVE, ['SP', 'GP'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.ADMN_FRZE,
FilingKey.CHANGE_OF_REGISTRATION,
FilingKey.CONV_FIRMS,
FilingKey.CORRCTN_FIRMS,
FilingKey.COURT_ORDER,
FilingKey.ADM_DISS_FIRMS,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER])),
# active business - general user
('general_user_cp', True, Business.State.ACTIVE, ['CP'], 'general', [BASIC_USER],
expected_lookup([FilingKey.AR_CP,
FilingKey.COA_CP,
FilingKey.COD_CP,
FilingKey.SPECIAL_RESOLUTION])),
('general_user_corps', True, Business.State.ACTIVE, ['BC', 'BEN', 'CC', 'ULC'], 'general', [BASIC_USER],
expected_lookup([FilingKey.AR_CORPS,
FilingKey.COA_CORPS,
FilingKey.COD_CORPS,
FilingKey.TRANSITION])),
('general_user_llc', True, Business.State.ACTIVE, ['LLC'], 'general', [BASIC_USER], []),
('general_user_firms', True, Business.State.ACTIVE, ['SP', 'GP'], 'general', [BASIC_USER],
expected_lookup([FilingKey.CHANGE_OF_REGISTRATION])),
# historical business - staff user
('staff_historical_cp', True, Business.State.HISTORICAL, ['CP'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.COURT_ORDER,
FilingKey.PUT_BACK_ON,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER])),
('staff_historical_corps', True, Business.State.HISTORICAL, ['BC', 'BEN', 'CC', 'ULC'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.COURT_ORDER,
FilingKey.PUT_BACK_ON,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER,
FilingKey.RESTRN_FULL_CORPS,
FilingKey.RESTRN_LTD_CORPS])),
('staff_historical_llc', True, Business.State.HISTORICAL, ['LLC'], 'staff', [STAFF_ROLE], []),
('staff_historical_firms', True, Business.State.HISTORICAL, ['SP', 'GP'], 'staff', [STAFF_ROLE],
expected_lookup([FilingKey.COURT_ORDER,
FilingKey.PUT_BACK_ON,
FilingKey.REGISTRARS_NOTATION,
FilingKey.REGISTRARS_ORDER])),
# historical business - general user
('general_user_historical_cp', True, Business.State.HISTORICAL, ['CP'], 'general', [BASIC_USER], []),
('general_user_historical_corps', True, Business.State.HISTORICAL, ['BC', 'BEN', 'CC', 'ULC'], 'general',
[BASIC_USER], []),
('general_user_historical_llc', True, Business.State.HISTORICAL, ['LLC'], 'general', [BASIC_USER], []),
('general_user_historical_firms', True, Business.State.HISTORICAL, ['SP', 'GP'], 'general', [BASIC_USER], []),
]
)
def test_get_allowed_filings_blocker_in_dissolution(monkeypatch, app, session, jwt, test_name, business_exists, state,
legal_types, username, roles, expected):
"""Assert that get allowed returns valid filings when business is in dissolution."""
token = helper_create_jwt(jwt, roles=roles, username=username)
headers = {'Authorization': 'Bearer ' + token}

def mock_auth(one, two): # pylint: disable=unused-argument; mocks of library methods
return headers[one]

with app.test_request_context():
monkeypatch.setattr('flask.request.headers.get', mock_auth)

for legal_type in legal_types:
business = None
identifier = (f'BC{random.SystemRandom().getrandbits(0x58)}')[:9]
business = factory_business(identifier=identifier,
entity_type=legal_type,
state=state)
with patch.object(type(business), 'in_dissolution', new_callable=PropertyMock) as mock_in_dissolution:
mock_in_dissolution.return_value = True
filing_types = get_allowed_filings(business, state, legal_type, jwt)
assert filing_types == expected


@patch('legal_api.models.User.find_by_jwt_token', return_value=User(id=1, login_source='BCSC'))
@patch('legal_api.services.authz.is_self_registered_owner_operator', return_value=True)
def test_are_digital_credentials_allowed_false_when_no_token(monkeypatch, app, session, jwt):
Expand Down

0 comments on commit 1a99962

Please sign in to comment.