Skip to content

Commit

Permalink
feat: fix contact info, and add tests for new action validations
Browse files Browse the repository at this point in the history
  • Loading branch information
lchen-2101 committed Nov 29, 2024
1 parent de8cc8e commit 5ce9133
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 180 deletions.
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ env = [
"FS_UPLOAD_CONFIG__MKDIR=true",
"FS_DOWNLOAD_CONFIG__PROTOCOL=file",
"ENV=TEST",
"MAIL_API_URL=http://mail-api:8765/internal/confirmation/send"
"MAIL_API_URL=http://mail-api:8765/internal/confirmation/send",
'REQUEST_VALIDATORS__SIGN_AND_SUBMIT=["check_lei_status","check_lei_tin","check_filing_exists","check_sub_accepted","check_voluntary_filer","check_contact_info"]'
]
testpaths = ["tests"]

Expand Down
2 changes: 1 addition & 1 deletion src/sbl_filing_api/entities/models/dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class FilingDAO(Base):
lei: Mapped[str]
tasks: Mapped[List[FilingTaskProgressDAO] | None] = relationship(lazy="selectin", cascade="all, delete-orphan")
institution_snapshot_id: Mapped[str] = mapped_column(nullable=True)
contact_info: Mapped[ContactInfoDAO] = relationship("ContactInfoDAO", lazy="joined")
contact_info: Mapped[ContactInfoDAO | None] = relationship("ContactInfoDAO", lazy="joined")
submissions: Mapped[List[SubmissionDAO] | None] = relationship(
"SubmissionDAO", lazy="select", order_by=desc(SubmissionDAO.submission_time)
)
Expand Down
7 changes: 6 additions & 1 deletion src/sbl_filing_api/entities/repos/submission_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,12 @@ async def update_contact_info(
session: AsyncSession, lei: str, filing_period: str, new_contact_info: ContactInfoDTO
) -> FilingDAO:
filing = await get_filing(session, lei=lei, filing_period=filing_period)
filing.contact_info = ContactInfoDAO(**new_contact_info.__dict__.copy(), filing=filing.id)
if filing.contact_info:
for key, value in new_contact_info.__dict__.items():
if key != "id":
setattr(filing.contact_info, key, value)
else:
filing.contact_info = ContactInfoDAO(**new_contact_info.__dict__.copy(), filing=filing.id)
return await upsert_helper(session, filing, FilingDAO)


Expand Down
20 changes: 10 additions & 10 deletions src/sbl_filing_api/services/request_action_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __call__(self, institution: Dict[str, Any], **kwargs):
try:
is_active = institution["lei_status"]["can_file"]
if not is_active:
return f"LEI status of {institution['lei_status_code']} cannot file."
return f"Cannot sign filing. LEI status of {institution['lei_status_code']} cannot file."
except Exception:
log.exception("Unable to determine lei status: %s", json.dumps(institution))
return "Unable to determine LEI status."
Expand All @@ -87,7 +87,7 @@ def __init__(self):

def __call__(self, institution: Dict[str, Any], **kwargs):
if not institution["tax_id"]:
return "TIN is required to file"
return "Cannot sign filing. TIN is required to file."


class CheckFilingExists(ActionValidator):
Expand All @@ -104,19 +104,20 @@ def __init__(self):
super().__init__("check_sub_accepted")

async def __call__(self, filing: FilingDAO, **kwargs):
submissions: List[SubmissionDAO] = await filing.awaitable_attrs.submissions
if not len(submissions) or submissions[0].state != SubmissionState.SUBMISSION_ACCEPTED:
filing.lei
filing.filing_period
return f"Cannot sign filing. Filing for {filing.lei} for period {filing.filing_period} does not have a latest submission in the SUBMISSION_ACCEPTED state."
if filing:
submissions: List[SubmissionDAO] = await filing.awaitable_attrs.submissions
if not len(submissions) or submissions[0].state != SubmissionState.SUBMISSION_ACCEPTED:
filing.lei
filing.filing_period
return f"Cannot sign filing. Filing for {filing.lei} for period {filing.filing_period} does not have a latest submission in the SUBMISSION_ACCEPTED state."


class CheckVoluntaryFiler(ActionValidator):
def __init__(self):
super().__init__("check_voluntary_filer")

def __call__(self, filing: FilingDAO, **kwargs):
if filing.is_voluntary is None:
if filing and filing.is_voluntary is None:
return f"Cannot sign filing. Filing for {filing.lei} for period {filing.filing_period} does not have a selection of is_voluntary defined."


Expand All @@ -125,7 +126,7 @@ def __init__(self):
super().__init__("check_contact_info")

def __call__(self, filing: FilingDAO, **kwargs):
if not filing.contact_info:
if filing and not filing.contact_info:
return f"Cannot sign filing. Filing for {filing.lei} for period {filing.filing_period} does not have contact info defined."


Expand All @@ -147,7 +148,6 @@ async def _set_context(request: Request):
period = request.path_params.get("period_code")
context = {"lei": lei, "period": period}
if lei and UserActionContext.INSTITUTION in requirements:

context = context | {UserActionContext.INSTITUTION: await get_institution_data(FiRequest(request, lei))}
if period and UserActionContext.FILING in requirements:
context = context | {UserActionContext.FILING: await repo.get_filing(request.state.db_session, lei, period)}
Expand Down
153 changes: 77 additions & 76 deletions tests/api/routers/test_filing_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,25 +997,26 @@ async def test_accept_submission(self, mocker: MockerFixture, app_fixture: FastA
async def test_good_sign_filing(
self, mocker: MockerFixture, app_fixture: FastAPI, authed_user_mock: Mock, get_filing_mock: Mock
):
mock = mocker.patch("sbl_filing_api.entities.repos.submission_repo.get_latest_submission")
mock.return_value = SubmissionDAO(
id=1,
counter=5,
submitter=UserActionDAO(
get_filing_mock.return_value.is_voluntary = True
get_filing_mock.return_value.submissions = [
SubmissionDAO(
id=1,
user_id="123456-7890-ABCDEF-GHIJ",
user_name="Test Submitter User",
user_email="[email protected]",
action_type=UserActionType.SUBMIT,
timestamp=datetime.datetime.now(),
),
filing=1,
state=SubmissionState.SUBMISSION_ACCEPTED,
validation_ruleset_version="v1",
submission_time=datetime.datetime.now(),
filename="file1.csv",
)
get_filing_mock.return_value.is_voluntary = False
counter=5,
submitter=UserActionDAO(
id=1,
user_id="123456-7890-ABCDEF-GHIJ",
user_name="Test Submitter User",
user_email="[email protected]",
action_type=UserActionType.SUBMIT,
timestamp=datetime.datetime.now(),
),
filing=1,
state=SubmissionState.SUBMISSION_ACCEPTED,
validation_ruleset_version="v1",
submission_time=datetime.datetime.now(),
filename="file1.csv",
)
]

add_sig_mock = mocker.patch("sbl_filing_api.entities.repos.submission_repo.add_user_action")
add_sig_mock.return_value = UserActionDAO(
Expand All @@ -1034,7 +1035,14 @@ async def test_good_sign_filing(
updated_filing_obj = deepcopy(get_filing_mock.return_value)
upsert_mock.return_value = updated_filing_obj

client = TestClient(app_fixture)
fi_data_mock = mocker.patch("sbl_filing_api.services.request_action_validator.get_institution_data")
fi_data_mock.return_value = {
"tax_id": "12-3456789",
"lei_status_code": "ISSUED",
"lei_status": {"code": "ISSUED", "name": "Issued", "can_file": True},
}

client = TestClient(app_fixture, headers={"authorization": "Bearer test123"})
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
add_sig_mock.assert_called_with(
ANY,
Expand All @@ -1057,81 +1065,74 @@ async def test_good_sign_filing(
async def test_errors_sign_filing(
self, mocker: MockerFixture, app_fixture: FastAPI, authed_user_mock: Mock, get_filing_mock: Mock
):
sub_mock = mocker.patch("sbl_filing_api.entities.repos.submission_repo.get_latest_submission")
send_email_mock = mocker.patch("sbl_filing_api.services.request_handler.send_confirmation_email")
send_email_mock.return_value = None
sub_mock.return_value = SubmissionDAO(
id=1,
submitter=UserActionDAO(

get_filing_mock.return_value.submissions = [
SubmissionDAO(
id=1,
user_id="1234-5678-ABCD-EFGH",
user_name="Test Submitter User",
user_email="[email protected]",
action_type=UserActionType.SUBMIT,
timestamp=datetime.datetime.now(),
),
filing=1,
state=SubmissionState.VALIDATION_SUCCESSFUL,
validation_ruleset_version="v1",
submission_time=datetime.datetime.now(),
filename="file1.csv",
)
submitter=UserActionDAO(
id=1,
user_id="1234-5678-ABCD-EFGH",
user_name="Test Submitter User",
user_email="[email protected]",
action_type=UserActionType.SUBMIT,
timestamp=datetime.datetime.now(),
),
filing=1,
state=SubmissionState.VALIDATION_SUCCESSFUL,
validation_ruleset_version="v1",
submission_time=datetime.datetime.now(),
filename="file1.csv",
)
]
get_filing_mock.return_value.contact_info = None

client = TestClient(app_fixture)
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
assert res.status_code == 403
assert (
res.json()["error_detail"]
== "Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have a latest submission the SUBMISSION_ACCEPTED state."
add_sig_mock = mocker.patch("sbl_filing_api.entities.repos.submission_repo.add_user_action")
add_sig_mock.return_value = UserActionDAO(
id=2,
user_id="123456-7890-ABCDEF-GHIJ",
user_name="Test User",
user_email="[email protected]",
timestamp=datetime.datetime.now(),
action_type=UserActionType.SIGN,
)

sub_mock.return_value = None
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
assert res.status_code == 403
assert (
res.json()["error_detail"]
== "Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have a latest submission the SUBMISSION_ACCEPTED state."
)
upsert_mock = mocker.patch("sbl_filing_api.entities.repos.submission_repo.upsert_filing")
updated_filing_obj = deepcopy(get_filing_mock.return_value)
upsert_mock.return_value = updated_filing_obj

sub_mock.return_value = SubmissionDAO(
id=1,
submitter=UserActionDAO(
id=1,
user_id="1234-5678-ABCD-EFGH",
user_name="Test Submitter User",
user_email="[email protected]",
action_type=UserActionType.SUBMIT,
timestamp=datetime.datetime.now(),
),
filing=1,
state=SubmissionState.SUBMISSION_ACCEPTED,
validation_ruleset_version="v1",
submission_time=datetime.datetime.now(),
filename="file1.csv",
)
fi_data_mock = mocker.patch("sbl_filing_api.services.request_action_validator.get_institution_data")
fi_data_mock.return_value = {
"tax_id": None,
"lei_status_code": "LAPSED",
"lei_status": {"code": "LAPSED", "name": "Lapsed", "can_file": False},
}

client = TestClient(app_fixture, headers={"authorization": "Bearer test123"})
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
assert res.status_code == 403
errors = res.json()["error_detail"]
assert (
res.json()["error_detail"]
== "Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have a selection of is_voluntary defined."
"Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have a latest submission in the SUBMISSION_ACCEPTED state."
in errors
)

get_filing_mock.return_value.is_voluntary = True
get_filing_mock.return_value.contact_info = None
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
assert res.status_code == 403
assert (
res.json()["error_detail"]
== "Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have contact info defined."
"Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have a selection of is_voluntary defined."
in errors
)
assert (
"Cannot sign filing. Filing for 1234567890ABCDEFGH00 for period 2024 does not have contact info defined."
in errors
)
assert "Cannot sign filing. TIN is required to file." in errors
assert "Cannot sign filing. LEI status of LAPSED cannot file." in errors

get_filing_mock.return_value = None
res = client.put("/v1/filing/institutions/1234567890ABCDEFGH00/filings/2024/sign")
assert res.status_code == 404
assert (
res.json()["error_detail"]
== "There is no Filing for LEI 1234567890ABCDEFGH00 in period 2024, unable to sign a non-existent Filing."
"There is no Filing for LEI 1234567890ABCDEFGH00 in period 2024, unable to sign a non-existent Filing."
in res.json()["error_detail"]
)

async def test_get_latest_sub_report(
Expand Down
Loading

0 comments on commit 5ce9133

Please sign in to comment.