Skip to content

Commit

Permalink
Add national party schedule_b endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
pkfec committed Apr 24, 2024
1 parent fee4f9a commit 00b9576
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 181 deletions.
14 changes: 14 additions & 0 deletions tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,3 +668,17 @@ def update_fulltext(obj, create, extracted, **kwargs):
obj.contributor_occupation_text = sa.func.to_tsvector(
obj.contributor_occupation
)


class NationalParty_ScheduleBFactory(BaseFactory):
class Meta:
model = models.NationalParty_ScheduleB

sub_id = factory.Sequence(lambda n: n)
report_year = 2024
two_year_transaction_period = 2024

@factory.post_generation
def update_fulltext(obj, create, extracted, **kwargs):
obj.disbursement_description_text = sa.func.to_tsvector(obj.disbursement_description_text)
obj.recipient_name_text = sa.func.to_tsvector(obj.recipient_name_text)
109 changes: 86 additions & 23 deletions tests/test_national_party.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from tests.common import ApiBaseTest
from webservices.rest import api
from webservices.schemas import NationalPartyScheduleASchema
from webservices.resources.national_party import NationalParty_ScheduleAView
from webservices.resources.national_party import NationalParty_ScheduleAView, NationalParty_ScheduleBView


class TestNationalParty(ApiBaseTest):
Expand Down Expand Up @@ -193,25 +193,25 @@ def test_invalid_zip(self):
)
self.assertEqual(response.status_code, 422)

def test_committee_contributor_type_filter(self):
def test_contributor_committee_type_filter(self):
[
factories.NationalParty_ScheduleAFactory(committee_contributor_type='S'),
factories.NationalParty_ScheduleAFactory(committee_contributor_type='S'),
factories.NationalParty_ScheduleAFactory(committee_contributor_type='P'),
factories.NationalParty_ScheduleAFactory(contributor_committee_type='S'),
factories.NationalParty_ScheduleAFactory(contributor_committee_type='S'),
factories.NationalParty_ScheduleAFactory(contributor_committee_type='P'),
]
results = self._results(
api.url_for(NationalParty_ScheduleAView, committee_contributor_type='S', **self.kwargs)
api.url_for(NationalParty_ScheduleAView, contributor_committee_type='S', **self.kwargs)
)
self.assertEqual(len(results), 2)

def test_committee_contributor_designation_type_filter(self):
def test_contributor_committee_designation_type_filter(self):
[
factories.NationalParty_ScheduleAFactory(committee_contributor_designation='J'),
factories.NationalParty_ScheduleAFactory(committee_contributor_designation='U'),
factories.NationalParty_ScheduleAFactory(committee_contributor_designation='J'),
factories.NationalParty_ScheduleAFactory(contributor_committee_designation='J'),
factories.NationalParty_ScheduleAFactory(contributor_committee_designation='U'),
factories.NationalParty_ScheduleAFactory(contributor_committee_designation='J'),
]
results = self._results(
api.url_for(NationalParty_ScheduleAView, committee_contributor_designation='J', **self.kwargs)
api.url_for(NationalParty_ScheduleAView, contributor_committee_designation='J', **self.kwargs)
)
self.assertEqual(len(results), 2)

Expand Down Expand Up @@ -255,9 +255,9 @@ def test_filter_party_account_type(self):
factories.NationalParty_ScheduleAFactory(
committee_id='C00000001',
committee_name='NRCC',
committee_contributor_name='',
committee_contributor_designation='U',
committee_contributor_state='VA',
contributor_committee_name='',
contributor_committee_designation='U',
contributor_committee_state='VA',
contributor_city='PLEASANTON',
contributor_employer='RETIRED',
contributor_first_name='CAROL',
Expand All @@ -273,7 +273,7 @@ def test_filter_party_account_type(self):
party_full='REPUBLICAN PARTY',
pdf_url='https://docquery.fec.gov/cgi-bin/fecimg/?202403209627299691',
receipt_desc='CONTRIBUTION',
party_account_receipt_type='32E',
receipt_type='32E',
receipt_type_desc='EARMARKED – RECOUNT',
recipient_committee_designation='U',
report_type='M3',
Expand All @@ -287,9 +287,9 @@ def test_filter_party_account_type(self):
factories.NationalParty_ScheduleAFactory(
committee_id='C00000002',
committee_name='NRCC',
committee_contributor_name='',
committee_contributor_designation='U',
committee_contributor_state='VA',
contributor_committee_name='',
contributor_committee_designation='U',
contributor_committee_state='VA',
contributor_city='PLEASANTON',
contributor_employer='RETIRED',
contributor_first_name='CAROL',
Expand All @@ -305,7 +305,7 @@ def test_filter_party_account_type(self):
party_full='REPUBLICAN PARTY',
pdf_url='https://docquery.fec.gov/cgi-bin/fecimg/?202403209627299691',
receipt_desc='CONTRIBUTION',
party_account_receipt_type='32E',
receipt_type='32E',
receipt_type_desc='EARMARKED – RECOUNT',
recipient_committee_designation='U',
report_type='M3',
Expand All @@ -319,9 +319,9 @@ def test_filter_party_account_type(self):
factories.NationalParty_ScheduleAFactory(
committee_id='C00000003',
committee_name='NRCC',
committee_contributor_name='',
committee_contributor_designation='U',
committee_contributor_state='VA',
contributor_committee_name='',
contributor_committee_designation='U',
contributor_committee_state='VA',
contributor_city='PLEASANTON',
contributor_employer='RETIRED',
contributor_first_name='CAROL',
Expand All @@ -337,7 +337,7 @@ def test_filter_party_account_type(self):
party_full='REPUBLICAN PARTY',
pdf_url='https://docquery.fec.gov/cgi-bin/fecimg/?202403209627299691',
receipt_desc='CONTRIBUTION',
party_account_receipt_type='32E',
receipt_type='32E',
receipt_type_desc='EARMARKED – RECOUNT',
recipient_committee_designation='U',
report_type='M3',
Expand All @@ -359,3 +359,66 @@ def test_filter_party_account_type(self):
api.url_for(NationalParty_ScheduleAView, party_account_type='RECOUNT', **self.kwargs)
)
self.assertEqual(len(results), 2)


class TestNationalPartyScheduleB(ApiBaseTest):
kwargs = {'two_year_transaction_period': 2024}

def test_schedule_b_multiple_two_year_transaction_period(self):
"""
testing schedule_b api can take multiple cycles now
"""
[ # noqa
factories.NationalParty_ScheduleBFactory(
report_year=2014, two_year_transaction_period=2014
),
factories.NationalParty_ScheduleBFactory(
report_year=2016, two_year_transaction_period=2016
),
factories.NationalParty_ScheduleBFactory(
report_year=2018, two_year_transaction_period=2018
),
]
response = self._response(
api.url_for(NationalParty_ScheduleBView, two_year_transaction_period=[2016, 2018],)
)
self.assertEqual(len(response['results']), 2)

def test_spender_committee_type_filter(self):
[
factories.NationalParty_ScheduleBFactory(spender_committee_type='S'),
factories.NationalParty_ScheduleBFactory(spender_committee_type='S'),
factories.NationalParty_ScheduleBFactory(spender_committee_type='P'),
]
results = self._results(
api.url_for(NationalParty_ScheduleBView, spender_committee_type='S', **self.kwargs)
)
self.assertEqual(len(results), 2)

def test_spender_org_type_filter(self):
[
factories.NationalParty_ScheduleBFactory(spender_committee_org_type='W'),
factories.NationalParty_ScheduleBFactory(spender_committee_org_type='W'),
factories.NationalParty_ScheduleBFactory(spender_committee_org_type='C'),
]
results = self._results(
api.url_for(NationalParty_ScheduleBView, spender_committee_org_type='W', **self.kwargs)
)
self.assertEqual(len(results), 2)

def test_line_number(self):
[
factories.NationalParty_ScheduleBFactory(line_number='21b', filing_form='F3X'),
factories.NationalParty_ScheduleBFactory(line_number='29', filing_form='F3X'),
]

results = self._results(
api.url_for(NationalParty_ScheduleBView, line_number='F3X-29')
)
self.assertEqual(len(results), 1)

# invalid line_number
response = self.app.get(
api.url_for(NationalParty_ScheduleBView, line_number='123')
)
self.assertEqual(response.status_code, 400)
53 changes: 38 additions & 15 deletions webservices/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -1366,36 +1366,26 @@ def make_seek_args(field=fields.Int, description=None):
'contributor_occupation': fields.List(Keyword, description=docs.CONTRIBUTOR_OCCUPATION),
'contributor_employer': fields.List(Keyword, description=docs.CONTRIBUTOR_EMPLOYER),
'image_number': fields.List(IStr, description=docs.IMAGE_NUMBER),
'contributor_committee_type': fields.List(Keyword, description=docs.CONTRIBUTOR_EMPLOYER),
'contribution_receipt_date': Date(
missing=None,
description='When sorting by `contb_receipt_dt`, this is populated with the \
`contb_receipt_dt` of the last result. However, you will need to pass the index \
of that last result to `last_index` to get the next page.'
description=' Filter by contribution receipt date '
),
'contribution_receipt_amount': fields.Float(
missing=None,
description='When sorting by `contb_receipt_amt`, this is populated with the \
`contb_receipt_amt` of the last result. However, you will need to pass the index \
of that last result to `last_index` to get the next page.'
description='Filter by contribution receipt amount'
),
'line_number': fields.Str(description=docs.LINE_NUMBER),
'is_individual': fields.Bool(missing=None, description=docs.IS_INDIVIDUAL),
'contributor_type': fields.List(
fields.Str(validate=validate.OneOf(['individual', 'committee'])),
description='Filters individual or committee contributions based on line number'
),
'committee_contributor_type': fields.List(
'contributor_committee_type': fields.List(
IStr(validate=validate.OneOf([
'', 'C', 'D', 'E', 'H', 'I', 'N', 'O', 'P', 'Q',
'S', 'U', 'V', 'W', 'X', 'Y', 'Z'])),
description=docs.COMMITTEE_TYPE,
),
# 'committee_contributor_organization_type': fields.List(
# IStr(validate=validate.OneOf(['', 'C', 'L', 'M', 'T', 'V', 'W'])),
# description=docs.ORGANIZATION_TYPE,
# ),
'committee_contributor_designation': fields.List(
'contributor_committee_designation': fields.List(
IStr(validate=validate.OneOf(['', 'A', 'J', 'P', 'U', 'B', 'D'])),
description=docs.DESIGNATION,
),
Expand All @@ -1405,11 +1395,44 @@ def make_seek_args(field=fields.Int, description=None):
IStr(validate=validate.OneOf(['', 'CONVENTION', 'HEADQUARTERS', 'RECOUNT'])),
description='National party account type',
),
'party_account_receipt_type': fields.List(
'receipt_type': fields.List(
IStr(validate=validate.OneOf([
'30', '30E', '30F', '30G', '30J', '30K', '30T',
'31', '31E', '31F', '31G', '31J', '31K', '31T',
'32', '32E', '32F', '32G', '32J', '32K', '32T'])),
description='National party account receipt type',
),
}

national_party_schedule_b = {
'committee_id': fields.List(Committee_ID, description=docs.COMMITTEE_ID),
'disbursement_description': fields.List(Keyword, description=docs.DISBURSEMENT_DESCRIPTION),
'disbursement_purpose_category': fields.List(IStr(validate=validate.OneOf(disbursment_purpose_list)),
description=docs.DISBURSEMENT_PURPOSE_CATEGORY),
'disbursement_amount': fields.Float(missing=None, description=docs.LAST_DISBURSEMENT_AMOUNT),
'disbursement_date': Date(missing=None, description=docs.LAST_DISBURSEMENT_DATE),
# 'line_number': fields.List(IStr, description=docs.LINE_NUMBER),
'line_number': fields.Str(description=docs.LINE_NUMBER),
'recipient_city': fields.List(IStr, description=docs.RECIPIENT_CITY),
'recipient_committee_id': fields.List(Committee_ID, description=docs.RECIPIENT_COMMITTEE_ID),
'recipient_name': fields.List(Keyword, description=docs.RECIPIENT_NAME),
'recipient_state': fields.List(IStr, description=docs.RECIPIENT_STATE),
'spender_committee_designation': fields.List(
IStr(validate=validate.OneOf(['', 'A', 'J', 'P', 'U', 'B', 'D'])),
description=docs.DESIGNATION,
),
'spender_committee_org_type': fields.List(
IStr(validate=validate.OneOf(['', 'C', 'L', 'M', 'T', 'V', 'W'])),
description=docs.ORGANIZATION_TYPE,
),
'spender_committee_type': fields.List(
IStr(validate=validate.OneOf([
'', 'C', 'D', 'E', 'H', 'I', 'N', 'O', 'P', 'Q',
'S', 'U', 'V', 'W', 'X', 'Y', 'Z'])),
description=docs.COMMITTEE_TYPE,
),
'two_year_transaction_period': fields.List(
TwoYearTransactionPeriod,
description=docs.TWO_YEAR_TRANSACTION_PERIOD,
),
}
Loading

0 comments on commit 00b9576

Please sign in to comment.