def test_stt_doesnt_allow_self_tipping(self): alice = self.make_participant('alice') with pytest.raises(NoSelfTipping): alice.set_tip_to(alice, EUR('10.00'))
def test_payout_quarantine(self, gba): self.make_exchange('mango-cc', 39, 0, self.homer) gba.return_value = self.bank_account with mock.patch.multiple(transactions, QUARANTINE='1 month'): with self.assertRaises(NotEnoughWithdrawableMoney): payout(self.db, self.homer_route, EUR('32.00'))
def test_parsing_currency_amount(self): expected = EUR('1.23') actual = self.db.one("SELECT %s", (expected, )) assert expected == actual
def test_record_exchange_fails_if_negative_balance(self): with pytest.raises(NegativeBalance): record_exchange(self.db, self.homer_route, EUR("-10.00"), EUR("0.41"), EUR(0), self.homer, 'pre')
def test_payout_no_route(self): self.make_exchange('mango-cc', 20, 0, self.david) with self.assertRaises(AssertionError): payout(self.db, None, EUR('1.00'))
def test_upcharge_at_target(self): actual = upcharge_card(PAYIN_CARD_TARGET['EUR']) expected = (EUR('94.19'), EUR('2.19'), EUR('0.32')) assert actual == expected assert actual[1] / actual[0] < EUR('0.024') # less than 2.4% fee
def test_skim_credit(self): actual = skim_credit(EUR('10.00'), self.bank_account) assert actual == (EUR('10.00'), EUR('0.00'), EUR('0.00'))
def test_schedule_renewals_finds_partial_matches(self): """ This test is designed to hit the `find_partial_match` function inside `Participant.schedule_renewals`. """ alice = self.make_participant('alice', email='*****@*****.**') bob = self.make_participant('bob', email='*****@*****.**') team = self.make_participant('team', kind='group', email='*****@*****.**') team.add_member(bob) alice.set_tip_to(bob, EUR('1.00'), renewal_mode=2) alice.set_tip_to(team, EUR('1.50'), renewal_mode=2) alice_card = self.upsert_route(alice, 'stripe-card', address='pm_card_visa') self.make_payin_and_transfer(alice_card, bob, EUR('2.00')) self.make_payin_and_transfer(alice_card, team, EUR('3.00')) new_schedule = alice.schedule_renewals() next_payday = compute_next_payday_date() expected_transfers = [{ 'tippee_id': bob.id, 'tippee_username': '******', 'amount': EUR('2.00'), }, { 'tippee_id': team.id, 'tippee_username': '******', 'amount': EUR('3.00'), }] assert len(new_schedule) == 1 assert new_schedule[0].amount == EUR('5.00') assert new_schedule[0].transfers == expected_transfers expected_renewal_date = next_payday + timedelta(weeks=1) assert new_schedule[0].execution_date == expected_renewal_date assert new_schedule[0].automatic is True # Trigger the initial "upcoming charge" notification self.db.run( "UPDATE scheduled_payins SET ctime = ctime - interval '12 hours'") send_upcoming_debit_notifications() emails = self.get_emails() assert len(emails) == 1 assert emails[0]['to'][0] == 'alice <*****@*****.**>' assert emails[0][ 'subject'] == 'Liberapay donation renewal: upcoming debit of €5.00' sp = self.db.one("SELECT * FROM scheduled_payins WHERE payin IS NULL") assert sp.notifs_count == 1 # Tweak the amount of the first donation. The renewal shouldn't be # pushed back and the payer shouldn't be notified. alice.set_tip_to(bob, EUR('0.50')) new_schedule = alice.schedule_renewals() assert len(new_schedule) == 1 assert new_schedule[0].amount == EUR('5.00') assert new_schedule[0].transfers == expected_transfers assert new_schedule[0].execution_date == expected_renewal_date assert new_schedule[0].automatic is True emails = self.get_emails() assert not emails # Stop the second donation. The renewal should be rescheduled and the # payer should be notified of that change. alice.stop_tip_to(team) new_schedule = alice.schedule_renewals() assert len(new_schedule) == 1 assert new_schedule[0].amount == EUR('2.00') assert new_schedule[0].transfers == [expected_transfers[0]] previous_renewal_date = expected_renewal_date expected_renewal_date = next_payday + timedelta(weeks=3) assert new_schedule[0].execution_date == expected_renewal_date assert new_schedule[0].automatic is True emails = self.get_emails() assert len(emails) == 1 assert emails[0]['to'][0] == 'alice <*****@*****.**>' assert emails[0][ 'subject'] == 'Liberapay donation renewal: your upcoming payment has changed' expected_sentence = LOCALE_EN.format( "The payment of €5.00 scheduled for {old_date} has been replaced by " "a payment of €2.00 on {new_date}.", old_date=previous_renewal_date, new_date=expected_renewal_date) assert expected_sentence in emails[0]['text']
def test_get_tip_distribution_handles_no_tips(self): expected = ([], 0.0, EUR('0.00')) actual = self.alice.get_tip_distribution() assert actual == expected
def test_pledging_isnt_giving(self): alice = self.make_participant('alice', balance=EUR(100)) bob = self.make_elsewhere('github', 58946, 'bob').participant alice.set_tip_to(bob, EUR('3.00')) assert alice.giving == EUR('0.00')
def test_cross_tip_doesnt_become_self_tip(self): alice = self.make_participant('alice', elsewhere='twitter') bob = self.make_elsewhere('twitter', 2, 'bob') alice.set_tip_to(bob.participant, EUR('1.00')) alice.take_over(bob, have_confirmation=True) self.db.self_check()
def test_cant_pledge_to_locked_accounts(self): alice = self.make_participant('alice') bob = self.make_stub(goal=EUR(-1)) with self.assertRaises(UserDoesntAcceptTips): alice.set_tip_to(bob, EUR('3.00'))
def test_only_funded_tips_count(self): alice = self.make_participant('alice') bob = self.make_participant('bob') carl = self.make_participant('carl') dana = self.make_participant('dana') alice_card = self.upsert_route(alice, 'stripe-card') alice.set_tip_to(dana, EUR('3.00')) self.make_payin_and_transfer(alice_card, dana, EUR('15.00')) alice.set_tip_to(bob, EUR('6.00')) self.make_payin_and_transfer(alice_card, bob, EUR('30.00')) bob.set_tip_to(alice, EUR('5.00')) bob.set_tip_to(dana, EUR('2.00')) carl.set_tip_to(dana, EUR('2.08')) assert alice.giving == EUR('9.00') assert alice.receiving == EUR('0.00') assert bob.giving == EUR('0.00') assert bob.receiving == EUR('6.00') assert carl.giving == EUR('0.00') assert carl.receiving == EUR('0.00') assert dana.receiving == EUR('3.00') assert dana.npatrons == 1 funded_tips = self.db.all( "SELECT amount FROM tips WHERE is_funded ORDER BY id") assert funded_tips == [3, 6]
def test_stt_fails_to_tip_unknown_people(self): alice = self.make_participant('alice') with pytest.raises(NoTippee): alice.set_tip_to('bob', EUR('1.00'))
def test_upcharge_full_in_rounded_case(self): actual = upcharge_card(EUR('5.00')) expected = upcharge_card(PAYIN_CARD_MIN['EUR']) assert actual == expected
def test_get_tip_distribution_handles_multiple_tips(self): self.alice.set_tip_to(self.bob, EUR('1.00')) self.make_payin_and_transfer(self.alice_card, self.bob, EUR('8.00')) carl = self.make_participant('carl') carl_card = self.upsert_route(carl, 'stripe-card') carl.set_tip_to(self.bob, EUR('3.00')) self.make_payin_and_transfer(carl_card, self.bob, EUR('3.00')) expected = ([ [EUR('1.00'), 1, EUR('1.00'), EUR('1.00'), 0.5, Decimal('0.25')], [EUR('3.00'), 1, EUR('3.00'), EUR('3.00'), 0.5, Decimal('0.75')] ], 2, EUR('4.00')) actual = self.bob.get_tip_distribution() assert actual == expected
def test_upcharge_at_min(self): actual = upcharge_card(PAYIN_CARD_MIN['EUR']) expected = (EUR('15.54'), EUR('0.54'), EUR('0.08')) assert actual == expected assert actual[1] / actual[0] < EUR('0.035') # less than 3.5% fee
def test_get_tip_distribution_ignores_old_or_nonfunded_tip(self): self.alice.set_tip_to(self.bob, EUR('3.00')) # funded self.alice.set_tip_to(self.bob, EUR('100.00')) # not funded expected = ([], 0, EUR('0.00')) actual = self.bob.get_tip_distribution() assert actual == expected
def test_upcharge_at_min_minus_one_cent(self): actual = upcharge_card(PAYIN_CARD_MIN['EUR'] - EUR('0.01')) expected = upcharge_card(PAYIN_CARD_MIN['EUR']) assert actual == expected
def test_payout_during_payday(self): self.make_exchange('mango-cc', 200, 0, self.homer) Payday.start() with self.assertRaises(PaydayIsRunning): payout(self.db, self.homer_route, EUR('97.35'))
def test_skim_credit_outside_sepa(self): actual = skim_credit(EUR('10.00'), self.bank_account_outside_sepa) assert actual == (EUR('7.07'), EUR('2.93'), EUR('0.43'))
def test_charge_bad_card(self): self.janet_route.set_attributes(address='-1') exchange = charge(self.db, self.janet_route, EUR('10.00'), 'http://localhost/') assert exchange.note.startswith( 'The value -1 is not valid (CardId) | Error ID: ')
def test_payout_amount_under_minimum(self, gba): self.make_exchange('mango-cc', 8, 0, self.homer) gba.return_value = self.bank_account_outside_sepa with self.assertRaises(FeeExceedsAmount): payout(self.db, self.homer_route, EUR('0.10'))
def test_charge_no_card(self): with self.assertRaises(AssertionError): charge(self.db, None, EUR('10.00'), 'http://localhost/')
def test_payout_invalidated_bank_account(self): self.make_exchange('mango-cc', 20, 0, self.homer) self.homer_route.invalidate() with self.assertRaises(AssertionError): payout(self.db, self.homer_route, EUR('10.00'))
def test_direct_debit_form(self): path = b'/janet/wallet/payin/direct-debit' self.janet.set_tip_to(self.david, EUR('10.00')) r = self.client.GET(path, auth_as=self.janet) assert r.code == 200
def test_close_raises_for_unknown_disbursement_strategy(self): alice = self.make_participant('alice', balance=EUR('0.00')) with pytest.raises(alice.UnknownDisbursementStrategy): alice.close('cheese')
def test_upcharge_basically_works(self): actual = upcharge_card(EUR('20.00')) expected = (EUR('20.65'), EUR('0.65'), EUR('0.10')) assert actual == expected
def test_sorting(self): amounts = [JPY('130'), EUR('99.58'), Money('79', 'KRW'), USD('35.52')] expected = sorted(amounts, key=lambda m: -m.convert('EUR').amount) actual = self.db.all("SELECT x FROM unnest(%s) x ORDER BY x DESC", (amounts, )) assert expected == actual
def test_stt_sets_tip_to(self): alice = self.make_participant('alice') bob = self.make_stub() alice.set_tip_to(bob, EUR('1.00')) actual = alice.get_tip_to(bob).amount assert actual == EUR('1.00')