Skip to content

Commit

Permalink
Merge pull request #4449 from fecgov/feature/4444-pac-party-total-end…
Browse files Browse the repository at this point in the history
…point

Fix PAC and Parties total endpoints
  • Loading branch information
lbeaufort authored Jul 13, 2020
2 parents f20028a + c7592a9 commit 11f4bb5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 22 deletions.
6 changes: 6 additions & 0 deletions data/migrations/V0202__rename_column_name.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
this migration file is for #4444. By change the column name, the endpoint will return all rows.
V0190 has the latest complete statement of this view.
*/

alter table public.ofec_totals_pac_party_vw rename sub_id to idx;
62 changes: 62 additions & 0 deletions tests/test_totals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from webservices.rest import api
from webservices.resources.totals import (
TotalsCommitteeView,
TotalsByCommitteeTypeView,
ScheduleAByStateRecipientTotalsView,
)

Expand Down Expand Up @@ -49,6 +50,67 @@
transaction_coverage_fields = {'transaction_coverage_date': None}


# test for endpoint: /totals/{committee_type}
class TestTotalsByCommitteeType(ApiBaseTest):
def test_pac_total_by_committee_type(self):
first_pac_total = {
'committee_id': 'C00001',
'committee_type': 'O',
'cycle': 2018,
'all_loans_received': 1,
'allocated_federal_election_levin_share': 2,
}
second_pac_total = {
'committee_id': 'C00002',
'committee_type': 'N',
'cycle': 2016,
'all_loans_received': 10,
'allocated_federal_election_levin_share': 20,
}
factories.TotalsPacFactory(**first_pac_total)
factories.TotalsPacFactory(**second_pac_total)

results = self._results(
api.url_for(TotalsByCommitteeTypeView, committee_type='pac')
)
assert len(results) == 2
assert results[0]['committee_id'] == 'C00001'
assert results[1]['committee_id'] == 'C00002'

def test_cycle_filter(self):
presidential_fields = {
'committee_id': 'C00001',
'cycle': 2016,
'candidate_contribution': 1,
'exempt_legal_accounting_disbursement': 2,
'federal_funds': 300,
}
factories.CommitteeTotalsPerCycleFactory(**presidential_fields)
results = self._results(
api.url_for(TotalsByCommitteeTypeView, cycle=2016, committee_type='presidential')
)
assert len(results) == 1
self.assertEqual(results[0]['cycle'], presidential_fields['cycle'])

def test_designation_filter(self):
party_fields = {
'committee_id': 'C00001',
'cycle': 2014,
'committee_name': 'REPUBLICAN COMMITTEE',
'committee_designation': 'U',
'committee_type': 'X',
'all_loans_received': 1,
'allocated_federal_election_levin_share': 2,
}
factories.TotalsPacFactory(**party_fields)
results = self._results(
api.url_for(TotalsByCommitteeTypeView, committee_designation='U', committee_type='party')
)
assert len(results) == 1
self.assertEqual(results[0]['committee_designation'], party_fields['committee_designation'])


# test for endpoint: /committee/{committee_id}/totals/
class TestTotals(ApiBaseTest):
def test_Presidential_totals(self):
committee_id = 'C8675309'
Expand Down
5 changes: 2 additions & 3 deletions webservices/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,9 @@ def make_seek_args(field=fields.Int, description=None):
'designation': fields.Str(description=docs.DESIGNATION),
}

totals_all = {
totals_by_committee_type = {
'cycle': fields.List(fields.Int, description=docs.RECORD_CYCLE),
'committee_type_full': fields.Str(description=docs.COMMITTEE_TYPE),
'committee_designation_full': fields.Str(description=docs.DESIGNATION),
'committee_designation': fields.List(fields.Str, description=docs.DESIGNATION),
'committee_id': fields.Str(description=docs.COMMITTEE_ID),
}

Expand Down
1 change: 0 additions & 1 deletion webservices/common/models/totals.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ class CandidateCommitteeTotalsHouseSenate(CandidateCommitteeTotals):
class CommitteeTotalsPacParty(CommitteeTotals):
__tablename__ = 'ofec_totals_pac_party_vw'

idx = db.Column('sub_id', db.Integer)
all_loans_received = db.Column(db.Numeric(30, 2))
allocated_federal_election_levin_share = db.Column(db.Numeric(30, 2))
coordinated_expenditures_by_party_committee = db.Column(db.Numeric(30, 2))
Expand Down
21 changes: 5 additions & 16 deletions webservices/resources/totals.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@
},
},
)
class TotalsView(utils.Resource):
class TotalsByCommitteeTypeView(utils.Resource):
@use_kwargs(args.paging)
@use_kwargs(args.totals_all)
@use_kwargs(args.totals_by_committee_type)
@use_kwargs(args.make_sort_args(default='-cycle'))
@marshal_with(schemas.CommitteeTotalsPageSchema(), apply=False)
def get(self, committee_id=None, committee_type=None, **kwargs):
Expand All @@ -91,16 +91,16 @@ def get(self, committee_id=None, committee_type=None, **kwargs):

def build_query(self, committee_id=None, committee_type=None, **kwargs):
totals_class, totals_schema = totals_schema_map.get(
self._resolve_committee_type(
committee_id=committee_id, committee_type=committee_type, **kwargs
),
committee_type_map.get(committee_type),
default_schemas,
)
query = totals_class.query
if committee_id is not None:
query = query.filter(totals_class.committee_id == committee_id)
if kwargs.get('cycle'):
query = query.filter(totals_class.cycle.in_(kwargs['cycle']))
if kwargs.get('committee_designation'):
query = query.filter(totals_class.committee_designation.in_(kwargs['committee_designation']))
if committee_type == 'pac':
query = query.filter(
models.CommitteeTotalsPacParty.committee_type.in_(pac_cmte_list)
Expand All @@ -117,17 +117,6 @@ def build_query(self, committee_id=None, committee_type=None, **kwargs):
)
return query, totals_class, totals_schema

def _resolve_committee_type(self, committee_id=None, committee_type=None, **kwargs):
if committee_id is not None:
query = models.CommitteeHistory.query.filter_by(committee_id=committee_id)
if kwargs.get('cycle'):
query = query.filter(models.CommitteeHistory.cycle.in_(kwargs['cycle']))
query = query.order_by(sa.desc(models.CommitteeHistory.cycle))
committee = query.first_or_404()
return committee.committee_type
elif committee_type is not None:
return committee_type_map.get(committee_type)


@doc(
tags=['financial'],
Expand Down
4 changes: 2 additions & 2 deletions webservices/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def forbidden(exception):
'/candidate/<candidate_id>/committees/history/',
'/candidate/<candidate_id>/committees/history/<int:cycle>/',
)
api.add_resource(totals.TotalsView, '/totals/<string:committee_type>/')
api.add_resource(totals.TotalsByCommitteeTypeView, '/totals/<string:committee_type>/')
api.add_resource(totals.TotalsCommitteeView, '/committee/<string:committee_id>/totals/')
api.add_resource(totals.CandidateTotalsView, '/candidate/<string:candidate_id>/totals/')
api.add_resource(reports.ReportsView, '/reports/<string:committee_type>/')
Expand Down Expand Up @@ -457,7 +457,7 @@ def forbidden(exception):
apidoc.register(reports.EFilingHouseSenateSummaryView, blueprint='v1')
apidoc.register(reports.EFilingPresidentialSummaryView, blueprint='v1')
apidoc.register(reports.EFilingPacPartySummaryView, blueprint='v1')
apidoc.register(totals.TotalsView, blueprint='v1')
apidoc.register(totals.TotalsByCommitteeTypeView, blueprint='v1')
apidoc.register(totals.CandidateTotalsView, blueprint='v1')
apidoc.register(totals.TotalsCommitteeView, blueprint='v1')
apidoc.register(sched_a.ScheduleAView, blueprint='v1')
Expand Down

0 comments on commit 11f4bb5

Please sign in to comment.