def test_payday_one_short(self, charge, get_tips_and_total):
        amount = decimal.Decimal(1.00)
        like_a_tip = {
            'amount': amount,
            'tippee': 'mjallday',
            'ctime': datetime.utcnow(),
            'claimed_time': datetime.utcnow(),
        }

        # success, success, claimed, failure
        tips = [like_a_tip, like_a_tip, like_a_tip, like_a_tip]
        get_tips_and_total.return_value = tips, amount

        payday_start = datetime.utcnow()
        participant = {
            'balance': 0,
            'id': self.participant_id,
            'balanced_account_uri': self.balanced_account_uri,
        }

        # in real-life we wouldn't be able to catch an error as the charge
        # method will swallow any errors and return false. we don't handle this
        # return value within payday_one but instead continue on trying to
        # use the remaining credit in the user's account to payout as many tips
        # as possible.
        # here we're hacking the system and throwing the exception so execution
        # stops since we're only testing this part of the method. that smells
        # like we need to refactor.
        charge.side_effect = Exception()
        with self.assertRaises(Exception):
            billing.payday_one(payday_start, participant)
        self.assertTrue(charge.called_with(self.participant_id,
                                           self.balanced_account_uri,
                                           amount))
    def test_payday_one_no_tips(self, get_tips_and_total):
        amount = decimal.Decimal(1.00)

        get_tips_and_total.return_value = [], amount
        payday_start = datetime.utcnow()
        participant = {
            'balance': 1,
            'id': self.participant_id,
            'balanced_account_uri': self.balanced_account_uri,
        }

        initial_payday = self._get_payday()
        billing.payday_one(payday_start, participant)
        resulting_payday = self._get_payday()

        self.assertEqual(initial_payday['ntippers'],
                         resulting_payday['ntippers'])
        self.assertEqual(initial_payday['ntips'],
                         resulting_payday['ntips'])
        self.assertEqual(initial_payday['nparticipants'] + 1,
                         resulting_payday['nparticipants'])
    def test_payday_one(self, log_tip, get_tips_and_total):
        amount = decimal.Decimal(1.00)
        like_a_tip = {
            'amount': amount,
            'tippee': 'mjallday',
            'ctime': datetime.utcnow(),
            'claimed_time': datetime.utcnow(),
        }

        # success, success, claimed, failure
        tips = [like_a_tip, like_a_tip, like_a_tip, like_a_tip]
        get_tips_and_total.return_value = tips, amount

        payday_start = datetime.utcnow()
        participant = {
            'balance': 1,
            'id': self.participant_id,
            'balanced_account_uri': self.balanced_account_uri,
        }

        return_values = [1, 1, 0, -1]
        return_values.reverse()

        def log_tip_return_values(*_):
            return return_values.pop()

        log_tip.side_effect = log_tip_return_values

        initial_payday = self._get_payday()
        billing.payday_one(payday_start, participant)
        resulting_payday = self._get_payday()

        self.assertEqual(initial_payday['ntippers'] + 1,
                         resulting_payday['ntippers'])
        self.assertEqual(initial_payday['ntips'] + 2,
                         resulting_payday['ntips'])
        self.assertEqual(initial_payday['nparticipants'] + 1,
                         resulting_payday['nparticipants'])