Example #1
0
class TestCandidateAggregates(ApiBaseTest):
    current_cycle = get_current_cycle()
    next_cycle = current_cycle + 2

    def setUp(self):
        super().setUp()
        self.candidate = factories.CandidateHistoryFutureFactory(
            candidate_id='S123',
            two_year_period=2012,
            candidate_election_year=2012,
        )
        self.committees = [
            factories.CommitteeHistoryFactory(cycle=2012, designation='P'),
            factories.CommitteeHistoryFactory(cycle=2012, designation='A'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate.candidate_id,
            election_years=[2008, 2012],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate.candidate_id,
                cand_election_year=election_year,
            ) for election_year in [2008, 2012]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate.candidate_id,
            cycle=2012,
            is_election=True,
            receipts=100,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate.candidate_id,
            cycle=2012,
            is_election=False,
            receipts=75,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate.candidate_id)
        db.session.flush()
        # Create two-year totals for both the target period (2011-2012) and the
        # previous period (2009-2010) for testing the `election_full` flag
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[0].committee_id,
            committee_designation='P',
            committee_type='S',
            fec_election_year=2012,
            election_yr_to_be_included=2012,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[1].committee_id,
            committee_designation='A',
            committee_type='S',
            fec_election_year=2012,
            election_yr_to_be_included=2012,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[1].committee_id,
            committee_designation='A',
            committee_type='S',
            fec_election_year=2010,
            election_yr_to_be_included=2012,
        )
        # Create a candidate_zero without a committee and $0 in CandidateTotal
        self.candidate_zero = factories.CandidateHistoryFutureFactory(
            candidate_id='H321',
            two_year_period=2018,
            candidate_election_year=2018,
            candidate_inactive=True,
        )
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_zero.candidate_id,
            election_years=[2018],
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_zero.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=0,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_zero.candidate_id,
            cycle=2018,
            is_election=True,
            receipts=0,
        )
        # Create data for a candidate who ran in 2017 and 2018

        self.candidate_17_18 = factories.CandidateHistoryFutureFactory(
            candidate_id='S456',
            two_year_period=2018,
            candidate_election_year=2018,
            candidate_inactive=False,
        )
        self.committees_17_18 = [
            factories.CommitteeHistoryFactory(cycle=2018, designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            election_years=[2018],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_17_18.candidate_id,
                cand_election_year=election_year,
            ) for election_year in [2017, 2018]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_17_18
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            cycle=2018,
            is_election=True,
            receipts=100,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=100,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_17_18.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            committee_id=self.committees_17_18[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2017,
            fec_election_year=2018,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            committee_id=self.committees_17_18[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2018,
            fec_election_year=2018,
        )
        # Create data for a candidate who ran just in 2017
        self.candidate_17_only = factories.CandidateHistoryFutureFactory(
            candidate_id='H456',
            two_year_period=2018,
            candidate_election_year=2017,
        )
        self.committees_17_only = [
            factories.CommitteeHistoryFactory(cycle=2018, designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            election_years=[2017],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_17_only.candidate_id,
                cand_election_year=election_year,
            ) for election_year in [2017]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_17_only
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            cycle=2018,
            is_election=True,
            receipts=150,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=150,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_17_only.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            committee_id=self.committees_17_only[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2017,
            fec_election_year=2018,
        )

        # Create data for future presidential - next_cycle. Use formula for future

        # Test full next_cycle and current_cycle 2-year totals

        self.candidate_20 = factories.CandidateHistoryFutureFactory(
            candidate_id='P456',
            two_year_period=self.current_cycle,
            candidate_election_year=self.next_cycle,
        )
        self.candidate_20 = factories.CandidateHistoryFutureFactory(
            candidate_id='P456',
            two_year_period=self.next_cycle,
            candidate_election_year=self.next_cycle,
        )
        # Candidate history won't have next_cycle yet
        self.committees_20 = [
            factories.CommitteeHistoryFactory(cycle=self.current_cycle,
                                              designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_20.candidate_id,
            election_years=[self.next_cycle],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_20.candidate_id,
                cand_election_year=election_year,
            ) for election_year in [self.next_cycle - 4, self.next_cycle]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_20
        ]
        # Full next_cycle
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_20.candidate_id,
            cycle=self.next_cycle,
            is_election=True,
            receipts=55000,
        )
        # current_cycle 2-year
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_20.candidate_id,
            cycle=self.current_cycle,
            is_election=False,
            receipts=25000,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_20.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_20.candidate_id,
            committee_id=self.committees_20[0].committee_id,
            committee_designation='P',
            committee_type='P',
            cand_election_year=self.next_cycle,
            fec_election_year=self.current_cycle,
        )

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_20.candidate_id,
            committee_id=self.committees_20[0].committee_id,
            committee_designation='P',
            committee_type='P',
            cand_election_year=self.next_cycle,
            fec_election_year=self.next_cycle,
        )

    def test_by_size(self):
        [
            factories.ScheduleABySizeFactory(
                committee_id=self.committees[0].committee_id,
                cycle=2012,
                total=50,
                size=200,
                count=20,
            ),
            factories.ScheduleABySizeFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150,
                size=200,
                count=20,
            ),
            factories.ScheduleABySizeFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2010,
                total=3,
                size=200,
                count=3,
            ),
        ]
        results = self._results(
            api.url_for(
                ScheduleABySizeCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        assert len(results) == 1
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 203,
            'size': 200,
            'count': 43,
        }
        assert results[0] == expected

        results = self._results(
            api.url_for(
                ScheduleABySizeCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
                election_full=False,
            ))
        assert len(results) == 1
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 200,
            'size': 200,
            'count': 40,
        }
        assert results[0] == expected

    def test_by_state(self):
        [
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[0].committee_id,
                cycle=2012,
                total=50,
                state='NY',
                state_full='New York',
                count=30,
            ),
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150,
                state='NY',
                state_full='New York',
                count=30,
            ),
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2010,
                total=10.01,
                state='NY',
                state_full='New York',
                count=3,
            ),
        ]
        results = self._results(
            api.url_for(
                ScheduleAByStateCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        assert len(results) == 1
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 210.01,
            'state': 'NY',
            'state_full': 'New York',
            'count': 63,
        }
        assert results[0] == expected

        results = self._results(
            api.url_for(
                ScheduleAByStateCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
                election_full=False,
            ))
        assert len(results) == 1
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 200,
            'state': 'NY',
            'state_full': 'New York',
            'count': 60,
        }
        assert results[0] == expected

    def test_by_state_candidate_totals(self):
        [
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[0].committee_id,
                cycle=2012,
                total=50.3,
                state='NY',
                state_full='New York',
                count=30,
            ),
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150.11,
                state='CT',
                state_full='New York',
                count=10,
            ),
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150.10,
                state='NJ',
                state_full='New Jersey',
                count=60,
            ),
        ]
        results = self._results(
            api.url_for(
                ScheduleAByStateCandidateTotalsView,
                candidate_id=self.candidate.candidate_id.lower(),
                cycle=2012,
            ))
        assert len(results) == 1
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 350.51,
            'count': 100,
        }
        assert results[0] == expected

    def test_totals(self):
        # 2-year totals
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
                election_full=False,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2012, 'receipts': 75})

        # Full-cycle totals (default is true)
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2012, 'receipts': 100})

        # candidate_zero
        # by default, load all candidates, current candidate should return
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_zero.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 0})

        # active candidate test: loading active candidates result nothing
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_zero.candidate_id,
                cycle=2018,
                is_active_candidate=True,
            ))
        assert len(results) == 0

        # active candidate test: loading inactive candidates result current one
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_zero.candidate_id,
                cycle=2018,
                is_active_candidate=False,
                election_full=False,
            ))
        assert len(results) == 1

        # candidate_17_18
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_18.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 100})

        # active candidats tst2: load inactive candidates result nothing
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_18.candidate_id,
                cycle=2018,
                is_active_candidate=False,
            ))
        assert len(results) == 0

        # active candidats tst3: load active candidates only
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_18.candidate_id,
                cycle=2018,
                is_active_candidate=True,
            ))
        assert len(results) == 1

        # candidate_17_only
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_only.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 150})

        # candidate_20
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_20.candidate_id,
                cycle=self.current_cycle,
                election_full=False,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {
            'cycle': self.current_cycle,
            'receipts': 25000
        })

    def test_totals_full(self):
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
                election_full='true',
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2012, 'receipts': 100})

        # candidate_20
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_20.candidate_id,
                cycle=self.next_cycle,
                election_full='true',
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {
            'cycle': self.next_cycle,
            'receipts': 55000
        })
Example #2
0
class TestCandidateAggregates(ApiBaseTest):

    current_cycle = get_current_cycle()
    next_cycle = current_cycle + 2

    def setUp(self):
        super().setUp()
        self.candidate = factories.CandidateHistoryFutureFactory(
            candidate_id='S123',
            two_year_period=2012,
            candidate_election_year=2012,
        )
        self.committees = [
            factories.CommitteeHistoryFactory(cycle=2012, designation='P'),
            factories.CommitteeHistoryFactory(cycle=2012, designation='A'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate.candidate_id,
            election_years=[2008, 2012],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate.candidate_id,
                cand_election_year=election_year)
            for election_year in [2008, 2012]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate.candidate_id,
            cycle=2012,
            is_election=True,
            receipts=100,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate.candidate_id,
            cycle=2012,
            is_election=False,
            receipts=75,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate.candidate_id)
        db.session.flush()
        # Create two-year totals for both the target period (2011-2012) and the
        # previous period (2009-2010) for testing the `election_full` flag
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[0].committee_id,
            committee_designation='P',
            committee_type='S',
            fec_election_year=2012,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[1].committee_id,
            committee_designation='A',
            committee_type='S',
            fec_election_year=2012,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate.candidate_id,
            committee_id=self.committees[1].committee_id,
            committee_designation='A',
            committee_type='S',
            fec_election_year=2010,
        )
        # Create a candidate_zero without a committee and $0 in CandidateTotal
        self.candidate_zero = factories.CandidateHistoryFutureFactory(
            candidate_id='H321',
            two_year_period=2018,
            candidate_election_year=2018,
        )
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_zero.candidate_id,
            election_years=[2018],
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_zero.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=0,
        )
        # Create data for a candidate who ran in 2017 and 2018

        self.candidate_17_18 = factories.CandidateHistoryFutureFactory(
            candidate_id='S456',
            two_year_period=2018,
            candidate_election_year=2018,
        )
        self.committees_17_18 = [
            factories.CommitteeHistoryFactory(cycle=2018, designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            election_years=[2018],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_17_18.candidate_id,
                cand_election_year=election_year)
            for election_year in [2017, 2018]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_17_18
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            cycle=2018,
            is_election=True,
            receipts=100,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=100,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_17_18.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            committee_id=self.committees_17_18[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2017,
            fec_election_year=2018,
        )
        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_18.candidate_id,
            committee_id=self.committees_17_18[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2018,
            fec_election_year=2018,
        )
        # Create data for a candidate who ran just in 2017
        self.candidate_17_only = factories.CandidateHistoryFutureFactory(
            candidate_id='H456',
            two_year_period=2018,
            candidate_election_year=2017,
        )
        self.committees_17_only = [
            factories.CommitteeHistoryFactory(cycle=2018, designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            election_years=[2017],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_17_only.candidate_id,
                cand_election_year=election_year) for election_year in [2017]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_17_only
        ]
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            cycle=2018,
            is_election=True,
            receipts=150,
        )
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            cycle=2018,
            is_election=False,
            receipts=150,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_17_only.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_17_only.candidate_id,
            committee_id=self.committees_17_only[0].committee_id,
            committee_designation='P',
            committee_type='S',
            cand_election_year=2017,
            fec_election_year=2018,
        )

        # Create data for future presidential - next_cycle. Use formula for future

        # Test full next_cycle and current_cycle 2-year totals

        self.candidate_20 = factories.CandidateHistoryFutureFactory(
            candidate_id='P456',
            two_year_period=self.current_cycle,
            candidate_election_year=self.next_cycle,
        )
        self.candidate_20 = factories.CandidateHistoryFutureFactory(
            candidate_id='P456',
            two_year_period=self.next_cycle,
            candidate_election_year=self.next_cycle,
        )
        #Candidate history won't have next_cycle yet
        self.committees_20 = [
            factories.CommitteeHistoryFactory(cycle=self.current_cycle,
                                              designation='P'),
        ]
        factories.CandidateDetailFactory(
            candidate_id=self.candidate_20.candidate_id,
            election_years=[self.next_cycle],
        )
        [
            factories.CandidateElectionFactory(
                candidate_id=self.candidate_20.candidate_id,
                cand_election_year=election_year)
            for election_year in [self.next_cycle - 4, self.next_cycle]
        ]
        [
            factories.CommitteeDetailFactory(committee_id=each.committee_id)
            for each in self.committees_20
        ]
        #Full next_cycle
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_20.candidate_id,
            cycle=self.next_cycle,
            is_election=True,
            receipts=55000,
        )
        #current_cycle 2-year
        factories.CandidateTotalFactory(
            candidate_id=self.candidate_20.candidate_id,
            cycle=self.current_cycle,
            is_election=False,
            receipts=25000,
        )
        factories.CandidateFlagsFactory(
            candidate_id=self.candidate_20.candidate_id)
        db.session.flush()

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_20.candidate_id,
            committee_id=self.committees_20[0].committee_id,
            committee_designation='P',
            committee_type='P',
            cand_election_year=self.next_cycle,
            fec_election_year=self.current_cycle,
        )

        factories.CandidateCommitteeLinkFactory(
            candidate_id=self.candidate_20.candidate_id,
            committee_id=self.committees_20[0].committee_id,
            committee_designation='P',
            committee_type='P',
            cand_election_year=self.next_cycle,
            fec_election_year=self.next_cycle,
        )

    def test_by_size(self):
        [
            factories.ScheduleABySizeFactory(
                committee_id=self.committees[0].committee_id,
                cycle=2012,
                total=50,
                size=200,
            ),
            factories.ScheduleABySizeFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150,
                size=200,
            ),
        ]
        results = self._results(
            api.url_for(
                ScheduleABySizeCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        self.assertEqual(len(results), 1)
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 200,
            'size': 200,
        }
        self.assertEqual(results[0], expected)

    def test_by_state(self):
        [
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[0].committee_id,
                cycle=2012,
                total=50,
                state='NY',
                state_full='New York',
            ),
            factories.ScheduleAByStateFactory(
                committee_id=self.committees[1].committee_id,
                cycle=2012,
                total=150,
                state='NY',
                state_full='New York',
            ),
        ]
        results = self._results(
            api.url_for(
                ScheduleAByStateCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        self.assertEqual(len(results), 1)
        expected = {
            'candidate_id': self.candidate.candidate_id,
            'cycle': 2012,
            'total': 200,
            'state': 'NY',
            'state_full': 'New York',
        }
        self.assertEqual(results[0], expected)

    def test_totals(self):
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2012, 'receipts': 75})

        # candidate_zero
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_zero.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 0})

        # candidate_17_18
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_18.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 100})

        # candidate_17_only
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_17_only.candidate_id,
                cycle=2018,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2018, 'receipts': 150})

        # candidate_20
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_20.candidate_id,
                cycle=self.current_cycle,
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {
            'cycle': self.current_cycle,
            'receipts': 25000
        })

    def test_totals_full(self):
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate.candidate_id,
                cycle=2012,
                election_full='true',
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {'cycle': 2012, 'receipts': 100})

        # candidate_20
        results = self._results(
            api.url_for(
                TotalsCandidateView,
                candidate_id=self.candidate_20.candidate_id,
                cycle=self.next_cycle,
                election_full='true',
            ))
        assert len(results) == 1
        assert_dicts_subset(results[0], {
            'cycle': self.next_cycle,
            'receipts': 55000
        })