def test_cch_success(self): self.hold, error = create_card_hold(self.db, self.obama, D('1.00')) assert isinstance(self.hold, braintree.Transaction) assert self.hold.status == 'authorized' assert self.hold.amount == D('10.00') assert error == '' assert self.obama.balance == P('obama').balance == 0
def test_capch_partial_amount(self): self.hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.obama, D('15.00'), self.hold) assert self.obama.balance == P('obama').balance == D('15.00') assert self.obama.get_credit_card_error() == ''
def test_capch_amount_under_minimum(self): self.hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.obama, D('0.01'), self.hold) assert self.obama.balance == P('obama').balance == D('9.41') assert self.obama.get_credit_card_error() == ''
def test_create_card_hold_no_card(self): customer_href = self.make_balanced_customer() bob = self.make_participant("bob", balanced_customer_href=customer_href, is_suspicious=False) hold, error = create_card_hold(self.db, bob, D("10.00")) bob2 = Participant.from_id(bob.id) assert error == "NoResultFound()" assert bob.last_bill_result == bob2.last_bill_result == None
def test_cch_deleted_card(self): bob = self.make_participant('bob', is_suspicious=False) route = ExchangeRoute.insert(bob, 'braintree-cc', 'foo') self.db.run("UPDATE exchange_routes SET is_deleted=true WHERE id=%s", (route.id,)) self.hold, error = create_card_hold(self.db, bob, D('10.00')) assert error == 'No credit card'
def test_create_card_hold_success(self): hold, error = create_card_hold(self.db, self.obama, D('1.00')) obama = Participant.from_id(self.obama.id) assert isinstance(hold, braintree.Transaction) assert hold.status == 'authorized' assert hold.amount == D('10.00') assert error == '' assert self.obama.balance == obama.balance == 0
def test_create_card_hold_no_card(self): customer_href = self.make_balanced_customer() bob = self.make_participant('bob', balanced_customer_href=customer_href, is_suspicious=False) hold, error = create_card_hold(self.db, bob, D('10.00')) bob2 = Participant.from_id(bob.id) assert error == 'NoResultFound()' assert bob.last_bill_result == bob2.last_bill_result == None
def test_capture_card_hold_amount_under_minimum(self): hold, error = create_card_hold(self.db, self.janet, D("20.00")) assert error == "" # sanity check capture_card_hold(self.db, self.janet, D("0.01"), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D("9.41") assert self.janet.last_bill_result == janet.last_bill_result == ""
def test_cch_deleted_card(self): bob = self.make_participant('bob', is_suspicious=False) route = ExchangeRoute.insert(bob, 'braintree-cc', 'foo') self.db.run("UPDATE exchange_routes SET is_deleted=true WHERE id=%s", (route.id, )) self.hold, error = create_card_hold(self.db, bob, D('10.00')) assert error == 'No credit card'
def test_create_card_hold_bad_card(self): customer_href = self.make_balanced_customer() card = balanced.Card(number="4444444444444448", expiration_year=2020, expiration_month=12).save() card.associate_to_customer(customer_href) bob = self.make_participant("bob", balanced_customer_href=customer_href, is_suspicious=False) hold, error = create_card_hold(self.db, bob, D("10.00")) assert error.startswith("402 Payment Required, ")
def test_capture_card_hold_amount_under_minimum(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.janet, D('0.01'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('9.41') assert self.janet.last_bill_result == janet.last_bill_result == ''
def test_capture_card_hold_amount_under_minimum(self): hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.obama, D('0.01'), hold) obama = Participant.from_id(self.obama.id) assert self.obama.balance == obama.balance == D('9.41') assert self.obama.get_credit_card_error() == ''
def test_capture_card_hold_partial_amount(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.janet, D('15.00'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('15.00') assert self.janet.get_credit_card_error() == ''
def test_capture_card_hold_partial_amount(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.janet, D('15.00'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('15.00') assert self.janet.last_bill_result == janet.last_bill_result == ''
def test_capture_card_hold_amount_under_minimum(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.janet, D('0.01'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('9.41') assert self.janet.get_credit_card_error() == ''
def test_payin_fetches_and_uses_existing_holds(self): self.janet.set_tip_to(self.homer, 20) hold, error = create_card_hold(self.db, self.janet, D(20)) assert hold is not None assert not error with mock.patch('gratipay.billing.payday.create_card_hold') as cch: cch.return_value = (None, None) self.create_card_holds() assert not cch.called, cch.call_args_list
def test_capch_too_high_amount(self): self.hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check with self.assertRaises(Exception): # How do I check the exception's msg here? capture_card_hold(self.db, self.obama, D('20.01'), self.hold) assert self.obama.balance == P('obama').balance == 0
def test_capture_card_hold_full_amount(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check assert hold.meta['state'] == 'new' capture_card_hold(self.db, self.janet, D('20.00'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('20.00') assert self.janet.last_bill_result == janet.last_bill_result == '' assert hold.meta['state'] == 'captured'
def test_capch_full_amount(self): self.hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check assert self.hold.status == 'authorized' capture_card_hold(self.db, self.obama, D('20.00'), self.hold) hold = braintree.Transaction.find(self.hold.id) assert self.obama.balance == P('obama').balance == D('20.00') assert self.obama.get_credit_card_error() == '' assert hold.status == 'submitted_for_settlement'
def test_payin_fetches_and_uses_existing_holds(self): team = self.make_team(owner=self.homer, is_approved=True) self.obama.set_subscription_to(team, '20.00') hold, error = create_card_hold(self.db, self.obama, D(20)) assert hold is not None assert not error with mock.patch('gratipay.billing.payday.create_card_hold') as cch: cch.return_value = (None, None) self.create_card_holds() assert not cch.called, cch.call_args_list
def test_capture_card_hold_full_amount(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check assert hold.meta['state'] == 'new' capture_card_hold(self.db, self.janet, D('20.00'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D('20.00') assert self.janet.get_credit_card_error() == '' assert hold.meta['state'] == 'captured'
def test_capture_card_hold_full_amount(self): hold, error = create_card_hold(self.db, self.janet, D("20.00")) assert error == "" # sanity check assert hold.meta["state"] == "new" capture_card_hold(self.db, self.janet, D("20.00"), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == D("20.00") assert self.janet.last_bill_result == janet.last_bill_result == "" assert hold.meta["state"] == "captured"
def test_payin_fetches_and_uses_existing_holds(self): team = self.make_team(owner=self.homer, is_approved=True) self.obama.set_payment_instruction(team, '20.00') hold, error = create_card_hold(self.db, self.obama, D(20)) assert hold is not None assert not error with mock.patch('gratipay.billing.payday.create_card_hold') as cch: cch.return_value = (None, None) self.create_card_holds() assert not cch.called, cch.call_args_list
def test_capture_card_hold_partial_amount(self): hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check capture_card_hold(self.db, self.obama, D('15.00'), hold) obama = Participant.from_id(self.obama.id) assert self.obama.balance == obama.balance == D('15.00') assert self.obama.get_credit_card_error() == '' # Clean up cancel_card_hold(hold)
def test_create_card_hold_multiple_cards(self): customer_href = self.make_balanced_customer() card = balanced.Card(number="4242424242424242", expiration_year=2020, expiration_month=12).save() card.associate_to_customer(customer_href) card = balanced.Card(number="4242424242424242", expiration_year=2030, expiration_month=12).save() card.associate_to_customer(customer_href) bob = self.make_participant("bob", balanced_customer_href=customer_href, is_suspicious=False) hold, error = create_card_hold(self.db, bob, D("10.00")) assert error == "MultipleResultsFound()"
def test_cch_failure(self, btsale): btsale.side_effect = Foobar self.hold, error = create_card_hold(self.db, self.obama, D('1.00')) assert self.hold is None assert error == "Foobar()" exchange = self.db.one("SELECT * FROM exchanges") assert exchange assert exchange.amount == D('9.41') assert exchange.fee == D('0.59') assert exchange.status == 'failed' assert self.obama.get_credit_card_error() == 'Foobar()' assert self.obama.balance == P('obama').balance == 0
def test_payin_cancels_existing_holds_of_insufficient_amounts(self, fch): self.janet.set_tip_to(self.homer, 30) hold, error = create_card_hold(self.db, self.janet, D(10)) assert not error fch.return_value = {self.janet.id: hold} with mock.patch('gratipay.billing.payday.create_card_hold') as cch: fake_hold = object() cch.return_value = (fake_hold, None) holds = self.create_card_holds() assert len(holds) == 1 assert holds[self.janet.id] is fake_hold assert hold.voided_at is not None
def test_create_card_hold_failure(self, Customer): Customer.side_effect = Foobar hold, error = create_card_hold(self.db, self.janet, D('1.00')) assert hold is None assert error == "Foobar()" exchange = self.db.one("SELECT * FROM exchanges") assert exchange assert exchange.amount assert exchange.status == 'failed' janet = Participant.from_id(self.janet.id) assert self.janet.last_bill_result == 'Foobar()' assert self.janet.balance == janet.balance == 0
def test_create_card_hold_bad_card(self): bob = self.make_participant('bob', balanced_customer_href='new', is_suspicious=False) card = balanced.Card(number='4444444444444448', expiration_year=2020, expiration_month=12).save() card.associate_to_customer(bob.balanced_customer_href) ExchangeRoute.insert(bob, 'balanced-cc', card.href) hold, error = create_card_hold(self.db, bob, D('10.00')) assert error.startswith('402 Payment Required, ')
def test_capture_card_hold_too_high_amount(self): hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check with self.assertRaises(balanced.exc.HTTPError): capture_card_hold(self.db, self.janet, D('20.01'), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == 0 # Clean up cancel_card_hold(hold)
def test_capture_card_hold_too_high_amount(self): hold, error = create_card_hold(self.db, self.janet, D("20.00")) assert error == "" # sanity check with self.assertRaises(balanced.exc.HTTPError): capture_card_hold(self.db, self.janet, D("20.01"), hold) janet = Participant.from_id(self.janet.id) assert self.janet.balance == janet.balance == 0 # Clean up cancel_card_hold(hold)
def test_create_card_hold_success(self): hold, error = create_card_hold(self.db, self.janet, D("1.00")) janet = Participant.from_id(self.janet.id) assert isinstance(hold, balanced.CardHold) assert hold.failure_reason is None assert hold.amount == 1000 assert hold.meta["state"] == "new" assert error == "" assert self.janet.balance == janet.balance == 0 # Clean up cancel_card_hold(hold)
def test_create_card_hold_success(self): hold, error = create_card_hold(self.db, self.janet, D('1.00')) janet = Participant.from_id(self.janet.id) assert isinstance(hold, balanced.CardHold) assert hold.failure_reason is None assert hold.amount == 1000 assert hold.meta['state'] == 'new' assert error == '' assert self.janet.balance == janet.balance == 0 # Clean up cancel_card_hold(hold)
def test_create_card_hold_bad_card(self): customer_href = self.make_balanced_customer() card = balanced.Card(number='4444444444444448', expiration_year=2020, expiration_month=12).save() card.associate_to_customer(customer_href) bob = self.make_participant('bob', balanced_customer_href=customer_href, is_suspicious=False) hold, error = create_card_hold(self.db, bob, D('10.00')) assert error.startswith('402 Payment Required, ')
def test_create_card_hold_failure(self, tfh): tfh.side_effect = Foobar hold, error = create_card_hold(self.db, self.janet, D('1.00')) assert hold is None assert error == "Foobar()" exchange = self.db.one("SELECT * FROM exchanges") assert exchange assert exchange.amount == D('9.41') assert exchange.fee == D('0.59') assert exchange.status == 'failed' janet = Participant.from_id(self.janet.id) assert self.janet.get_credit_card_error() == 'Foobar()' assert self.janet.balance == janet.balance == 0
def test_sync_with_balanced(self): with mock.patch('gratipay.billing.exchanges.record_exchange_result') as rer: rer.side_effect = Foobar() hold, error = create_card_hold(self.db, self.janet, D('20.00')) assert error == '' # sanity check with self.assertRaises(Foobar): capture_card_hold(self.db, self.janet, D('10.00'), hold) exchange = self.db.one("SELECT * FROM exchanges") assert exchange.status == 'pre' sync_with_balanced(self.db) exchange = self.db.one("SELECT * FROM exchanges") assert exchange.status == 'succeeded' assert Participant.from_username('janet').balance == 10
def test_create_card_hold_bad_card(self): bob = self.make_participant('bob', balanced_customer_href='new', is_suspicious=False) card = balanced.Card( number='4444444444444448', expiration_year=2020, expiration_month=12 ).save() card.associate_to_customer(bob.balanced_customer_href) ExchangeRoute.insert(bob, 'balanced-cc', card.href) hold, error = create_card_hold(self.db, bob, D('10.00')) assert error.startswith('402 Payment Required, ')
def test_capture_card_hold_too_high_amount(self): hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check with self.assertRaises(Exception): # How do I check the exception's msg here? capture_card_hold(self.db, self.obama, D('20.01'), hold) obama = Participant.from_id(self.obama.id) assert self.obama.balance == obama.balance == 0 # Clean up cancel_card_hold(hold)
def test_sync_with_balanced(self): with mock.patch("gratipay.billing.exchanges.record_exchange_result") as rer: rer.side_effect = Foobar() hold, error = create_card_hold(self.db, self.janet, D("20.00")) assert error == "" # sanity check with self.assertRaises(Foobar): capture_card_hold(self.db, self.janet, D("10.00"), hold) exchange = self.db.one("SELECT * FROM exchanges") assert exchange.status == "pre" sync_with_balanced(self.db) exchange = self.db.one("SELECT * FROM exchanges") assert exchange.status == "succeeded" assert Participant.from_username("janet").balance == 10
def test_payin_cancels_existing_holds_of_insufficient_amounts(self, fch): team = self.make_team(owner=self.homer, is_approved=True) self.janet.set_subscription_to(team, '30.00') hold, error = create_card_hold(self.db, self.janet, D(10)) assert not error fch.return_value = {self.janet.id: hold} with mock.patch('gratipay.billing.payday.create_card_hold') as cch: fake_hold = object() cch.return_value = (fake_hold, None) holds = self.create_card_holds() assert len(holds) == 1 assert holds[self.janet.id] is fake_hold assert hold.voided_at is not None
def test_payin_cancels_existing_holds_of_insufficient_amounts(self, fch): team = self.make_team(owner=self.homer, is_approved=True) self.obama.set_subscription_to(team, '30.00') hold, error = create_card_hold(self.db, self.obama, D(10)) assert not error fch.return_value = {self.obama.id: hold} with mock.patch('gratipay.billing.payday.create_card_hold') as cch: fake_hold = object() cch.return_value = (fake_hold, None) holds = self.create_card_holds() hold = braintree.Transaction.find(hold.id) assert len(holds) == 1 assert holds[self.obama.id] is fake_hold assert hold.status == 'voided'
def test_capture_card_hold_full_amount(self): hold, error = create_card_hold(self.db, self.obama, D('20.00')) assert error == '' # sanity check assert hold.status == 'authorized' capture_card_hold(self.db, self.obama, D('20.00'), hold) hold = braintree.Transaction.find(hold.id) obama = Participant.from_id(self.obama.id) assert self.obama.balance == obama.balance == D('20.00') assert self.obama.get_credit_card_error() == '' assert hold.status == 'submitted_for_settlement' # Clean up cancel_card_hold(hold)
def test_sync_with_balanced_deletes_charges_that_didnt_happen(self): with mock.patch('gratipay.billing.exchanges.record_exchange_result') as rer \ , mock.patch('balanced.CardHold.capture') as capture: rer.side_effect = capture.side_effect = Foobar hold, error = create_card_hold(self.db, self.janet, D('33.67')) assert error == '' # sanity check with self.assertRaises(Foobar): capture_card_hold(self.db, self.janet, D('7.52'), hold) exchange = self.db.one("SELECT * FROM exchanges") assert exchange.status == 'pre' sync_with_balanced(self.db) exchanges = self.db.all("SELECT * FROM exchanges") assert not exchanges assert Participant.from_username('janet').balance == 0
def test_cch_multiple_cards(self): bob = self.make_participant('bob', is_suspicious=False) customer_id = bob.get_braintree_account().id for i in range(2): result = braintree.PaymentMethod.create({ "customer_id": customer_id, "payment_method_nonce": Nonces.Transactable }) assert result.is_success ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token) self.hold, error = create_card_hold(self.db, bob, D('100.00')) assert error == ''
def test_payin_cancels_existing_holds_of_insufficient_amounts(self, fch): team = self.make_team(owner=self.homer, is_approved=True) self.obama.set_payment_instruction(team, '30.00') hold, error = create_card_hold(self.db, self.obama, D(10)) assert not error fch.return_value = {self.obama.id: hold} with mock.patch('gratipay.billing.payday.create_card_hold') as cch: fake_hold = object() cch.return_value = (fake_hold, None) holds = self.create_card_holds() hold = braintree.Transaction.find(hold.id) assert len(holds) == 1 assert holds[self.obama.id] is fake_hold assert hold.status == 'voided'
def test_cch_bad_card(self): bob = self.make_participant('bob', is_suspicious=False) customer_id = bob.get_braintree_account().id result = braintree.PaymentMethod.create({ "customer_id": customer_id, "payment_method_nonce": Nonces.Transactable }) assert result.is_success ExchangeRoute.insert(bob, 'braintree-cc', result.payment_method.token) # https://developers.braintreepayments.com/ios+python/reference/general/testing#test-amounts # $2002 is upcharged to $2062, which corresponds to 'Invalid Tax Amount' self.hold, error = create_card_hold(self.db, bob, D('2002.00')) assert self.hold is None assert error.startswith('Invalid Tax Amount')
def f(p): amount = p.giving_today if p.old_balance < 0: amount -= p.old_balance if p.id in holds: charge_amount = upcharge(amount)[0] if holds[p.id].amount >= charge_amount: return else: # The amount is too low, cancel the hold and make a new one cancel_card_hold(holds.pop(p.id)) hold, error = create_card_hold(self.db, p, amount) if error: return 1 else: holds[p.id] = hold