From 382ae96419a6a354a4aa45fb07e6944b391af02f Mon Sep 17 00:00:00 2001 From: William Palin Date: Tue, 5 Mar 2024 17:25:46 -0500 Subject: [PATCH 1/2] tests(disclosures): Add tests for expanded disclosure APIs --- cl/disclosures/factories.py | 42 ++++++++++++++++++++++++- cl/disclosures/tests.py | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/cl/disclosures/factories.py b/cl/disclosures/factories.py index e37b121be1..3cdc40b8f0 100644 --- a/cl/disclosures/factories.py +++ b/cl/disclosures/factories.py @@ -2,7 +2,16 @@ from factory.django import DjangoModelFactory from factory.fuzzy import FuzzyInteger -from cl.disclosures.models import FinancialDisclosure, Investment, Position +from cl.disclosures.models import ( + Debt, + FinancialDisclosure, + Gift, + Investment, + NonInvestmentIncome, + Position, + Reimbursement, + SpouseIncome, +) class InvestmentFactory(DjangoModelFactory): @@ -13,6 +22,37 @@ class Meta: description = Faker("sentence") +class GiftFactory(DjangoModelFactory): + class Meta: + model = Gift + + description = Faker("sentence") + source = Faker("sentence") + + +class ReimbursementFactory(DjangoModelFactory): + class Meta: + model = Reimbursement + + location = Faker("city") + purpose = Faker("sentence") + + +class DebtFactory(DjangoModelFactory): + class Meta: + model = Debt + + +class NonInvestmentIncomeFactory(DjangoModelFactory): + class Meta: + model = NonInvestmentIncome + + +class SpousalIncomeFactory(DjangoModelFactory): + class Meta: + model = SpouseIncome + + class FinancialDisclosurePositionFactory(DjangoModelFactory): class Meta: model = Position diff --git a/cl/disclosures/tests.py b/cl/disclosures/tests.py index a33226dfd1..4a103dcc53 100644 --- a/cl/disclosures/tests.py +++ b/cl/disclosures/tests.py @@ -9,9 +9,13 @@ from timeout_decorator import timeout_decorator from cl.disclosures.factories import ( + DebtFactory, FinancialDisclosureFactory, FinancialDisclosurePositionFactory, + GiftFactory, InvestmentFactory, + ReimbursementFactory, + SpousalIncomeFactory, ) from cl.disclosures.models import ( CODES, @@ -133,6 +137,31 @@ def setUpTestData(cls) -> None: InvestmentFactory.create_batch( 10, financial_disclosure=fd, redacted=True ) + DebtFactory.create( + financial_disclosure=fd, creditor_name="JP Morgan Chase" + ) + DebtFactory.create_batch(10, financial_disclosure=fd, redacted=False) + SpousalIncomeFactory.create( + financial_disclosure=fd, + source_type="A big Trust Fund", + ) + SpousalIncomeFactory.create_batch( + 10, financial_disclosure=fd, redacted=False + ) + GiftFactory.create( + financial_disclosure=fd, + source="John Oliver", + description="Luxury Motor Coach", + value="2,000,000.00 dollars", + ) + GiftFactory.create_batch(10, financial_disclosure=fd, redacted=False) + ReimbursementFactory.create( + financial_disclosure=fd, + location="Honolulu, Hawaii", + ) + ReimbursementFactory.create_batch( + 10, financial_disclosure=fd, redacted=False + ) async def test_disclosure_position_api(self) -> None: """Can we query the financial disclosure position API?""" @@ -207,6 +236,38 @@ async def test_filter_related_object(self) -> None: r = await self.async_client.get(self.path, q) self.assertEqual(r.json()["count"], 1, msg="Wrong disclosure count") + async def test_gift_filtering(self) -> None: + """Can we filter gifts by description?""" + self.path = reverse("gift-list", kwargs={"version": "v3"}) + self.q = {"description": "Luxury Motor Coach"} + r = await self.async_client.get(self.path, self.q) + self.assertEqual(r.json()["count"], 1, msg="Failed Gift filter") + + async def test_reimbursement_filtering(self) -> None: + """Can we filter reimbursements by location?""" + self.path = reverse("reimbursement-list", kwargs={"version": "v3"}) + self.q = {"location__icontains": "hawaii"} + r = await self.async_client.get(self.path, self.q) + self.assertEqual( + r.json()["count"], 1, msg="Failed Reimbursement filter" + ) + + async def test_spousal_income_filtering(self) -> None: + """Can we filter spousal income by source_type?""" + self.path = reverse("spouseincome-list", kwargs={"version": "v3"}) + self.q = {"source_type__icontains": "trust fund"} + r = await self.async_client.get(self.path, self.q) + self.assertEqual( + r.json()["count"], 1, msg="Failed Spousal Income filter" + ) + + async def test_debt_filtering(self) -> None: + """Can we filter debts by creditor?""" + self.path = reverse("debt-list", kwargs={"version": "v3"}) + self.q = {"creditor_name__icontains": "JP Morgan"} + r = await self.async_client.get(self.path, self.q) + self.assertEqual(r.json()["count"], 1, msg="Failed Debt filter") + class DisclosureReactLoadTest(BaseSeleniumTest): def setUp(self) -> None: From 15ee35f42cf3df8ed613e0fb5a2d7e0d4d86933c Mon Sep 17 00:00:00 2001 From: William Palin Date: Tue, 5 Mar 2024 17:26:22 -0500 Subject: [PATCH 2/2] feat(disclousures): Update filters for disclosures Add better filtering for all disclosure endpoints --- cl/disclosures/filters.py | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/cl/disclosures/filters.py b/cl/disclosures/filters.py index 7322ca7559..2c528e14d1 100644 --- a/cl/disclosures/filters.py +++ b/cl/disclosures/filters.py @@ -37,7 +37,13 @@ class AgreementFilter(NoEmptyFilterSet): class Meta: model = Agreement fields = disclosure_fields.copy() - fields.update({"parties_and_terms": ALL_TEXT_LOOKUPS}) + fields.update( + { + "parties_and_terms": ALL_TEXT_LOOKUPS, + "date_raw": ALL_TEXT_LOOKUPS, + "redacted": BOOLEAN_LOOKUPS, + } + ) class DebtFilter(NoEmptyFilterSet): @@ -49,6 +55,14 @@ class DebtFilter(NoEmptyFilterSet): class Meta: model = Debt fields = disclosure_fields.copy() + fields.update( + { + "creditor_name": ALL_TEXT_LOOKUPS, + "description": ALL_TEXT_LOOKUPS, + "value_code": ["exact"], + "redacted": BOOLEAN_LOOKUPS, + } + ) class FinancialDisclosureFilter(NoEmptyFilterSet): @@ -113,6 +127,9 @@ class Meta: "id": INTEGER_LOOKUPS, "date_created": DATETIME_LOOKUPS, "date_modified": DATETIME_LOOKUPS, + "source": ALL_TEXT_LOOKUPS, + "description": ALL_TEXT_LOOKUPS, + "value": ALL_TEXT_LOOKUPS, "redacted": BOOLEAN_LOOKUPS, } @@ -133,6 +150,7 @@ class Meta: "income_during_reporting_period_code": ["exact"], "transaction_during_reporting_period": ALL_TEXT_LOOKUPS, "transaction_value_code": ["exact"], + "redacted": BOOLEAN_LOOKUPS, } ) @@ -146,6 +164,14 @@ class NonInvestmentIncomeFilter(NoEmptyFilterSet): class Meta: model = NonInvestmentIncome fields = disclosure_fields.copy() + fields.update( + { + "date_raw": ALL_TEXT_LOOKUPS, + "source_type": ALL_TEXT_LOOKUPS, + "income_amount": ALL_TEXT_LOOKUPS, + "redacted": BOOLEAN_LOOKUPS, + } + ) class PositionFilter(NoEmptyFilterSet): @@ -157,6 +183,13 @@ class PositionFilter(NoEmptyFilterSet): class Meta: model = Position fields = disclosure_fields.copy() + fields.update( + { + "position": ALL_TEXT_LOOKUPS, + "organization_name": ALL_TEXT_LOOKUPS, + "redacted": BOOLEAN_LOOKUPS, + } + ) class ReimbursementFilter(NoEmptyFilterSet): @@ -168,6 +201,16 @@ class ReimbursementFilter(NoEmptyFilterSet): class Meta: model = Reimbursement fields = disclosure_fields.copy() + fields.update( + { + "date_raw": ALL_TEXT_LOOKUPS, + "location": ALL_TEXT_LOOKUPS, + "source": ALL_TEXT_LOOKUPS, + "purpose": ALL_TEXT_LOOKUPS, + "items_paid_or_provided": ALL_TEXT_LOOKUPS, + "redacted": BOOLEAN_LOOKUPS, + } + ) class SpouseIncomeFilter(NoEmptyFilterSet): @@ -179,3 +222,10 @@ class SpouseIncomeFilter(NoEmptyFilterSet): class Meta: model = SpouseIncome fields = disclosure_fields.copy() + fields.update( + { + "date_raw": ALL_TEXT_LOOKUPS, + "source_type": ALL_TEXT_LOOKUPS, + "redacted": BOOLEAN_LOOKUPS, + } + )