Skip to content

Commit

Permalink
fix: set non-required fields as nullable (#63)
Browse files Browse the repository at this point in the history
closes #62
  • Loading branch information
lchen-2101 authored Dec 13, 2023
1 parent 648f07f commit a699231
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 28 deletions.
28 changes: 14 additions & 14 deletions src/entities/models/dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@ class FinancialInstitutionDao(AuditMixin, Base):
domains: Mapped[List["FinancialInstitutionDomainDao"]] = relationship(
"FinancialInstitutionDomainDao", back_populates="fi"
)
tax_id: Mapped[str] = mapped_column(String(9), unique=True)
rssd_id: Mapped[int] = mapped_column(unique=True)
primary_federal_regulator_id: Mapped[str] = mapped_column(ForeignKey("federal_regulator.id"))
tax_id: Mapped[str] = mapped_column(String(9), unique=True, nullable=True)
rssd_id: Mapped[int] = mapped_column(unique=True, nullable=True)
primary_federal_regulator_id: Mapped[str] = mapped_column(ForeignKey("federal_regulator.id"), nullable=True)
primary_federal_regulator: Mapped["FederalRegulatorDao"] = relationship(lazy="selectin")
hmda_institution_type_id: Mapped[str] = mapped_column(ForeignKey("hmda_institution_type.id"))
hmda_institution_type_id: Mapped[str] = mapped_column(ForeignKey("hmda_institution_type.id"), nullable=True)
hmda_institution_type: Mapped["HMDAInstitutionTypeDao"] = relationship(lazy="selectin")
sbl_institution_type_id: Mapped[str] = mapped_column(ForeignKey("sbl_institution_type.id"))
sbl_institution_type_id: Mapped[str] = mapped_column(ForeignKey("sbl_institution_type.id"), nullable=True)
sbl_institution_type: Mapped["SBLInstitutionTypeDao"] = relationship(lazy="selectin")
hq_address_street_1: Mapped[str] = mapped_column(nullable=False)
hq_address_street_2: Mapped[str]
hq_address_street_1: Mapped[str]
hq_address_street_2: Mapped[str] = mapped_column(nullable=True)
hq_address_city: Mapped[str]
hq_address_state_code: Mapped[str] = mapped_column(ForeignKey("address_state.code"))
hq_address_state: Mapped["AddressStateDao"] = relationship(lazy="selectin")
hq_address_zip: Mapped[str] = mapped_column(String(5), nullable=False)
parent_lei: Mapped[str] = mapped_column(String(20))
parent_legal_name: Mapped[str]
parent_rssd_id: Mapped[int]
top_holder_lei: Mapped[str] = mapped_column(String(20))
top_holder_legal_name: Mapped[str]
top_holder_rssd_id: Mapped[int]
hq_address_zip: Mapped[str] = mapped_column(String(5))
parent_lei: Mapped[str] = mapped_column(String(20), nullable=True)
parent_legal_name: Mapped[str] = mapped_column(nullable=True)
parent_rssd_id: Mapped[int] = mapped_column(nullable=True)
top_holder_lei: Mapped[str] = mapped_column(String(20), nullable=True)
top_holder_legal_name: Mapped[str] = mapped_column(nullable=True)
top_holder_rssd_id: Mapped[int] = mapped_column(nullable=True)


class FinancialInstitutionDomainDao(AuditMixin, Base):
Expand Down
26 changes: 13 additions & 13 deletions src/entities/models/dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ class Config:


class FinancialInstitutionBase(BaseModel):
lei: str
name: str


class FinancialInstitutionDto(FinancialInstitutionBase):
lei: str
tax_id: str
rssd_id: int
primary_federal_regulator_id: str
hmda_institution_type_id: str
sbl_institution_type_id: str
tax_id: str | None = None
rssd_id: int | None = None
primary_federal_regulator_id: str | None = None
hmda_institution_type_id: str | None = None
sbl_institution_type_id: str | None = None
hq_address_street_1: str
hq_address_street_2: str
hq_address_street_2: str | None = None
hq_address_city: str
hq_address_state_code: str
hq_address_zip: str
parent_lei: str
parent_legal_name: str
parent_rssd_id: int
top_holder_lei: str
top_holder_legal_name: str
top_holder_rssd_id: int
parent_lei: str | None = None
parent_legal_name: str | None = None
parent_rssd_id: int | None = None
top_holder_lei: str | None = None
top_holder_legal_name: str | None = None
top_holder_rssd_id: int | None = None

class Config:
from_attributes = True
Expand Down
16 changes: 16 additions & 0 deletions src/entities/repos/institutions_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ async def upsert_institution(session: AsyncSession, fi: FinancialInstitutionDto)
session.add(db_fi)
else:
db_fi.name = fi.name
db_fi.tax_id = fi.tax_id
db_fi.rssd_id = fi.rssd_id
db_fi.primary_federal_regulator_id = fi.primary_federal_regulator_id
db_fi.hmda_institution_type_id = fi.hmda_institution_type_id
db_fi.sbl_institution_type_id = fi.sbl_institution_type_id
db_fi.hq_address_street_1 = fi.hq_address_street_1
db_fi.hq_address_street_2 = fi.hq_address_street_2
db_fi.hq_address_city = fi.hq_address_city
db_fi.hq_address_state_code = fi.hq_address_state_code
db_fi.hq_address_zip = fi.hq_address_zip
db_fi.parent_lei = fi.parent_lei
db_fi.parent_legal_name = fi.parent_legal_name
db_fi.parent_rssd_id = fi.parent_rssd_id
db_fi.top_holder_lei = fi.top_holder_lei
db_fi.top_holder_legal_name = fi.top_holder_legal_name
db_fi.top_holder_rssd_id = fi.top_holder_rssd_id
await session.commit()
return db_fi

Expand Down
46 changes: 46 additions & 0 deletions tests/api/routers/test_institutions_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,52 @@ def test_create_institution_authed(self, mocker: MockerFixture, app_fixture: Fas
assert res.status_code == 200
assert res.json()[1].get("name") == "testName"

def test_create_institution_only_required_fields(
self, mocker: MockerFixture, app_fixture: FastAPI, authed_user_mock: Mock
):
upsert_institution_mock = mocker.patch("entities.repos.institutions_repo.upsert_institution")
upsert_institution_mock.return_value = FinancialInstitutionDao(
name="testName",
lei="testLei",
hq_address_street_1="Test Address Street 1",
hq_address_city="Test City 1",
hq_address_state_code="VA",
hq_address_zip="00000",
)
upsert_group_mock = mocker.patch("oauth2.oauth2_admin.OAuth2Admin.upsert_group")
upsert_group_mock.return_value = "leiGroup"
client = TestClient(app_fixture)
res = client.post(
"/v1/institutions/",
json={
"name": "testName",
"lei": "testLei",
"hq_address_street_1": "Test Address Street 1",
"hq_address_city": "Test City 1",
"hq_address_state_code": "VA",
"hq_address_zip": "00000",
},
)
assert res.status_code == 200
assert res.json()[1].get("name") == "testName"
assert res.json()[1].get("tax_id") is None

def test_create_institution_missing_required_field(
self, mocker: MockerFixture, app_fixture: FastAPI, authed_user_mock: Mock
):
client = TestClient(app_fixture)
res = client.post(
"/v1/institutions/",
json={
"name": "testName",
"lei": "testLei",
"hq_address_street_1": "Test Address Street 1",
"hq_address_city": "Test City 1",
"hq_address_state_code": "VA",
},
)
assert res.status_code == 422

def test_create_institution_authed_no_permission(self, app_fixture: FastAPI, auth_mock: Mock):
claims = {
"name": "test",
Expand Down
42 changes: 41 additions & 1 deletion tests/entities/repos/test_institutions_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,50 @@ async def test_add_institution(self, transaction_session: AsyncSession):
res = await repo.get_institutions(transaction_session)
assert len(res) == 4

async def test_add_institution_only_required_fields(
self, transaction_session: AsyncSession, query_session: AsyncSession
):
await repo.upsert_institution(
transaction_session,
FinancialInstitutionDao(
name="Minimal Bank 123",
lei="MINBANK123",
hq_address_street_1="Minimal Address Street 1",
hq_address_city="Minimal City 1",
hq_address_state_code="FL",
hq_address_zip="22222",
),
)
res = await repo.get_institution(query_session, "MINBANK123")
assert res is not None
assert res.tax_id is None

async def test_add_institution_missing_required_fields(
self, transaction_session: AsyncSession, query_session: AsyncSession
):
with pytest.raises(Exception) as e:
await repo.upsert_institution(
transaction_session,
FinancialInstitutionDao(
name="Minimal Bank 123",
lei="MINBANK123",
),
)
assert "not null constraint failed" in str(e.value).lower()
res = await repo.get_institution(query_session, "MINBANK123")
assert res is None

async def test_update_institution(self, transaction_session: AsyncSession):
await repo.upsert_institution(
transaction_session,
FinancialInstitutionDao(name="Test Bank 234", lei="TESTBANK123"),
FinancialInstitutionDao(
name="Test Bank 234",
lei="TESTBANK123",
hq_address_street_1="Test Address Street 1",
hq_address_city="Test City 1",
hq_address_state_code="GA",
hq_address_zip="00000",
),
)
res = await repo.get_institutions(transaction_session)
assert len(res) == 3
Expand Down

0 comments on commit a699231

Please sign in to comment.